scalar += rdonly_untrusted_mem reaches adjust_ptr_min_max_vals() with the
pointer as the source register. The untrusted PTR_TO_MEM case returns there
without updating the scalar destination, leaving stale verifier state.

Reject that addition before the early return. Pointer += scalar remains
handled by the existing untrusted-memory rule.

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

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index c8d980fdd709..c6b350f9585a 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14823,6 +14823,14 @@ static int adjust_reg_min_max_vals(struct 
bpf_verifier_env *env,
                                 * This is legal, but we have to reverse our
                                 * src/dest handling in computing the range
                                 */
+                               if (opcode == BPF_ADD &&
+                                   base_type(src_reg->type) == PTR_TO_MEM &&
+                                   (src_reg->type & PTR_UNTRUSTED)) {
+                                       verbose(env, "R%d tried to add from %s 
to scalar\n",
+                                               insn->dst_reg,
+                                               reg_type_str(env, 
src_reg->type));
+                                       return -EACCES;
+                               }
                                err = mark_chain_precision(env, insn->dst_reg);
                                if (err)
                                        return err;

-- 
2.34.1


Reply via email to