When scalar += pointer is handled in adjust_ptr_min_max_vals(), the
destination register inherits the pointer type and id from the source
pointer. For PTR_TO_STACK, the inherited pointer state also has to carry
the stack frame number.

Without the frame number copy, a stack pointer derived inside a callee
through scalar += fp can be recorded as pointing to frame 0. Stack reads
and writes through that register can then update or consult the caller
frame while the actual instruction uses the callee frame.

Copy the frame number when PTR_TO_STACK state is inherited by the
commuted arithmetic form.

Signed-off-by: Yiyang Chen <[email protected]>
---
 kernel/bpf/verifier.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 52be0a118cce0..58017141d52b7 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13796,11 +13796,14 @@ static int adjust_ptr_min_max_vals(struct 
bpf_verifier_env *env,
                return -EACCES;
        }
 
-       /* In case of 'scalar += pointer', dst_reg inherits pointer type and id.
-        * The id may be overwritten later if we create a new variable offset.
+       /* In case of 'scalar += pointer', dst_reg inherits pointer type, id,
+        * and for stack pointers also the frame number. The id may be 
overwritten
+        * later if we create a new variable offset.
         */
        dst_reg->type = ptr_reg->type;
        dst_reg->id = ptr_reg->id;
+       if (base_type(ptr_reg->type) == PTR_TO_STACK)
+               dst_reg->frameno = ptr_reg->frameno;
 
        if (!check_reg_sane_offset_scalar(env, off_reg, ptr_reg->type) ||
            !check_reg_sane_offset_ptr(env, ptr_reg, ptr_reg->type))
-- 
2.34.1


Reply via email to