On Mon, 2026-07-13 at 06:16 +0000, Yiyang Chen wrote:
> check_stack_range_initialized() validates helper ranges byte by byte, but
> bpf_is_spilled_reg() only checks the slot-wide spill marker. For a CAP_BPF
> load, a narrow scalar spill marks only the covered bytes as STACK_SPILL. An
> untouched sibling remains STACK_INVALID, but the helper still accepts the
> read when the slot contains a spilled scalar.
> 
> Require the byte being checked to be STACK_SPILL before accepting the
> slot-wide scalar spill state.
> 
> Fixes: 354e8f1970f8 ("bpf: Support <8-byte scalar spill and refill")
> Signed-off-by: Yiyang Chen <[email protected]>
> ---
>  kernel/bpf/verifier.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 03e2202cca13d..c971cf34c760b 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -6785,7 +6785,8 @@ static int check_stack_range_initialized(
>                       goto mark;
>               }
>  
> -             if (bpf_is_spilled_reg(&state->stack[spi]) &&
> +             if (*stype == STACK_SPILL &&
> +                 bpf_is_spilled_reg(&state->stack[spi]) &&

Sorry, could you please explain again what's wrong with the original check?
Here it is:

                if (bpf_is_spilled_reg(&state->stack[spi]) &&
                    (state->stack[spi].spilled_ptr.type == SCALAR_VALUE || 
env->allow_ptr_leaks)) {
                        ... accepted ...
                }

And it says: if there is a register spill at 'spi':
- always allow access if the spilled register is scalar
- when allow_ptr_leaks is true, allow access when spilled
  register is either scalar or pointer.

The goal here is to avoid leaking pointers, and pointers are always 8-bytes.

>                   (state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
>                    env->allow_ptr_leaks)) {
>                       if (clobber) {

pw-bot: cr.

Reply via email to