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

