mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
bpf: Preserve pointer spill metadata during half-slot cleanup
__clean_func_state() cleans dead stack slots in 4-byte halves. When the
high half of a STACK_SPILL slot is dead and the low half remains live,
cleanup converts the live low half to STACK_MISC or STACK_ZERO and clears
the saved spilled_ptr metadata.
That conversion is safe only for scalar spills. For a pointer spill, this
metadata clear lets a later 32-bit fill from the still-live half avoid the
normal non-scalar register-fill check and be treated as an ordinary scalar
stack read.
Leave non-scalar spill slots intact in this half-live shape. This is
conservative for pruning and preserves the existing
check_stack_read_fixed_off() rejection path for partial fills from pointer
spills.
Fixes: be23266b4a ("bpf: 4-byte precise clean_verifier_state")
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
Link: https://lore.kernel.org/r/20260617-f01-06-half-slot-pointer-spill-v2-1-42b9cdc3cf64@mails.tsinghua.edu.cn
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
3d8e6fef15
commit
3a354149bc
@@ -436,12 +436,10 @@ static void __clean_func_state(struct bpf_verifier_env *env,
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Only destroy spilled_ptr when hi half is dead.
|
||||
* If hi half is still live with STACK_SPILL, the
|
||||
* spilled_ptr metadata is needed for correct state
|
||||
* comparison in stacksafe().
|
||||
* is_spilled_reg() is using slot_type[7], but
|
||||
* is_spilled_scalar_after() check either slot_type[0] or [4]
|
||||
* Only scalar spills can be degraded to raw stack bytes
|
||||
* when their high half is dead. Pointer spills need the
|
||||
* saved spilled_ptr metadata so partial fills keep
|
||||
* rejecting as non-scalar register fills.
|
||||
*/
|
||||
if (!hi_live) {
|
||||
struct bpf_reg_state *spill = &st->stack[i].spilled_ptr;
|
||||
@@ -449,6 +447,9 @@ static void __clean_func_state(struct bpf_verifier_env *env,
|
||||
if (lo_live && stype == STACK_SPILL) {
|
||||
u8 val = STACK_MISC;
|
||||
|
||||
if (spill->type != SCALAR_VALUE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* 8 byte spill of scalar 0 where half slot is dead
|
||||
* should become STACK_ZERO in lo 4 bytes.
|
||||
|
||||
Reference in New Issue
Block a user