The untrusted PTR_TO_MEM early return skips pointer offset tracking
because accesses go through probe-read handling. Moving it after full
pointer-state propagation ensures scalar += untrusted_pointer leaves the
destination as PTR_TO_MEM instead of an unrelated scalar.

Fixes: f2362a57aeff ("bpf: allow void* cast using bpf_rdonly_cast()")
Signed-off-by: Yiyang Chen <[email protected]>
---
 kernel/bpf/verifier.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 085cbd5222737..18fb6267692c5 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13763,13 +13763,6 @@ static int adjust_ptr_min_max_vals(struct 
bpf_verifier_env *env,
                return -EACCES;
        }
 
-       /*
-        * Accesses to untrusted PTR_TO_MEM are done through probe
-        * instructions, hence no need to track offsets.
-        */
-       if (base_type(ptr_reg->type) == PTR_TO_MEM && (ptr_reg->type & 
PTR_UNTRUSTED))
-               return 0;
-
        switch (base_type(ptr_reg->type)) {
        case PTR_TO_CTX:
        case PTR_TO_MAP_VALUE:
@@ -13809,6 +13802,13 @@ static int adjust_ptr_min_max_vals(struct 
bpf_verifier_env *env,
                *dst_reg = *ptr_reg;
        }
 
+       /*
+        * Accesses to untrusted PTR_TO_MEM are done through probe
+        * instructions, hence no need to track offsets.
+        */
+       if (base_type(ptr_reg->type) == PTR_TO_MEM && (ptr_reg->type & 
PTR_UNTRUSTED))
+               return 0;
+
        if (!check_reg_sane_offset_scalar(env, off_reg, ptr_reg->type) ||
            !check_reg_sane_offset_ptr(env, ptr_reg, ptr_reg->type))
                return -EINVAL;
-- 
2.34.1


Reply via email to