bpf: Don't promote bogus looking registers after null check.
authorDaniel Borkmann <daniel@iogearbox.net>
Wed, 5 Jan 2022 19:35:13 +0000 (11:35 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 5 Jan 2022 20:00:19 +0000 (12:00 -0800)
If we ever get to a point again where we convert a bogus looking <ptr>_or_null
typed register containing a non-zero fixed or variable offset, then lets not
reset these bounds to zero since they are not and also don't promote the register
to a <ptr> type, but instead leave it as <ptr>_or_null. Converting to a unknown
register could be an avenue as well, but then if we run into this case it would
allow to leak a kernel pointer this way.

Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index b70c66c..c8d9e76 100644 (file)
@@ -9079,15 +9079,15 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
 {
        if (type_may_be_null(reg->type) && reg->id == id &&
            !WARN_ON_ONCE(!reg->id)) {
-               /* Old offset (both fixed and variable parts) should
-                * have been known-zero, because we don't allow pointer
-                * arithmetic on pointers that might be NULL.
-                */
                if (WARN_ON_ONCE(reg->smin_value || reg->smax_value ||
                                 !tnum_equals_const(reg->var_off, 0) ||
                                 reg->off)) {
-                       __mark_reg_known_zero(reg);
-                       reg->off = 0;
+                       /* Old offset (both fixed and variable parts) should
+                        * have been known-zero, because we don't allow pointer
+                        * arithmetic on pointers that might be NULL. If we
+                        * see this happening, don't convert the register.
+                        */
+                       return;
                }
                if (is_null) {
                        reg->type = SCALAR_VALUE;