Re: [PATCH bpf 1/2] bpf: Validate stack arg reads against caller state
From: Weiming Shi
Date: Wed Oct 21 2026 - 04:06:48 EST
Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> 于2026年10月21日周三 08:03写道:
>
> On Wed, Oct 07, 2026 at 10:42 AM Weiming Shi <bestswngs@xxxxxxxxx> wrote:
> > then read a slot that the caller never allocated or initialized. Async
> > callback verification also starts at curframe zero, so subtracting one
> > to find a caller can underflow the frame array.
>
> Sync callbacks are broken too and this patch doesn't help:
> *(u64 *)(r11 - 8) = r6;
> r1 = 1;
> r2 = cb ll;
> ...
> call bpf_loop;
> where cb() has 6 args in BTF and does r1 = *(u64 *)(r11 + 8).
> The slot is written, so check_outgoing_stack_args() called from
> push_callback_call() passes. push_stack() copies stack_arg_regs[]
> of the caller and the load in cb() gets the state of r6.
> set_loop_callback_state() marks R3-R5 as not init, but stack args
> stay readable.
> At run-time bpf_loop(), when not inlined, calls cb(i, ctx, 0, 0, 0).
> x86 JIT reads arg6 from r9 and arg7 from the stack frame of bpf_loop().
> The verifier thinks it's a map value, but it's garbage.
>
> No helper or kfunc passes more than 5 args to a callback.
> Reject callbacks with bpf_in_stack_arg_cnt() in push_callback_call().
>
> > + if (!vstate->curframe) {
> > + verbose(env, "invalid read from stack arg off %d without caller\n", off);
> > + return -EACCES;
> > + }
> > +
>
> Only async callback can get here with curframe == 0.
> With the above it's rejected earlier. Drop this check.
>
> Add sync and async callback tests to patch 2.
>
> Also mention in the log that
> commit 4286f5deee14 ("bpf: Validate outgoing stack args when btf_prepare_func_args fails")
> closed this hole for the first call only.
>
> pw-bot: cr
Thanks for your review. v2 sent.