[PATCH bpf v2] bpf: Fix wrong frame passed to check_fastcall_stack_contract() in check_stack_read_fixed_off()

From: Ömer Mete Kaya

Date: Sun Sep 27 2026 - 19:29:48 EST


check_stack_read_fixed_off() calls check_fastcall_stack_contract() with
'state' (always the current frame, vstate->frame[vstate->curframe])
instead of 'reg_state' (the frame the pointer refers to).

In a bpf2bpf call where a callee reads from a PTR_TO_STACK pointing
into the caller's frame, 'reg_state' and 'state' are different:
'reg_state' is the caller's frame, while 'state' is the callee's.
Passing 'state' causes the fastcall contract to be checked against the
callee's subprog instead of the caller's, leaving the caller's fastcall
region unprotected and potentially causing an incorrect fastcall rewrite.

The three sibling functions all pass the frame the pointer refers to:
check_stack_write_fixed_off -> passes 'state' (ptr's frame)
check_stack_write_var_off -> passes 'state' (ptr's frame)
check_stack_read_var_off -> passes 'ptr_state' (ptr's frame)

Only check_stack_read_fixed_off was incorrectly passing the current frame
instead of the pointer's frame.

Fix by passing 'reg_state' instead of 'state', matching the pattern used
by all sibling functions.

Fixes: 5b5f51bff1b6 ("bpf: no_caller_saved_registers attribute for helper calls")
Signed-off-by: Ömer Mete Kaya <omermetekaya0@xxxxxxxxx>
---
Changes in v2:
- Fix commit message: sibling write functions pass the frame the
pointer refers to, not curframe. Reported by bpf-ci bot.

kernel/bpf/verifier.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1cd92336309b..5c523a9bde6b 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -4020,7 +4020,7 @@ static int check_stack_read_fixed_off(struct bpf_verifier_env *env,
reg = &reg_state->stack[spi].spilled_ptr;

mark_stack_slot_scratched(env, spi);
- check_fastcall_stack_contract(env, state, env->insn_idx, off);
+ check_fastcall_stack_contract(env, reg_state, env->insn_idx, off);

/*
* Refine the in-progress load record's origin to the source stack slot.
--
2.55.0