From: Alexei Starovoitov Date: Mon, 23 Mar 2026 02:24:10 +0000 (-0700) Subject: selftests/bpf: Test 32-bit scalar spill pruning in stacksafe() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b4f1a29c704f2c28f32dca5fea6d173891c16a9;p=thirdparty%2Fkernel%2Flinux.git selftests/bpf: Test 32-bit scalar spill pruning in stacksafe() Add a test verifying that stacksafe() correctly handles 32-bit scalar spills when comparing stack states for equivalence during state pruning. A 32-bit scalar spill creates slot[0-3] = STACK_INVALID and slot[4-7] = STACK_SPILL. Without the im=4 check in stacksafe(), the STACK_SPILL vs STACK_MISC mismatch at byte 4 causes pruning to fail, forcing the verifier to re-explore a path that is provably safe. Acked-by: Eduard Zingerman Link: https://lore.kernel.org/r/20260323022410.75444-2-alexei.starovoitov@gmail.com Signed-off-by: Alexei Starovoitov --- diff --git a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c index 893d3bb024a0b..a2b6d99628da0 100644 --- a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c +++ b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c @@ -1279,4 +1279,41 @@ __naked void stack_noperfmon_spill_32bit_onto_64bit_slot(void) : __clobber_all); } +/* + * stacksafe(): check if 32-bit scalar spill in old state is considered + * equivalent to STACK_MISC in cur state. + * 32-bit scalar spill creates slot[0-3] = STACK_MISC, slot[4-7] = STACK_SPILL. + * Without 32-bit spill support in stacksafe(), the STACK_SPILL vs STACK_MISC + * mismatch at slot[4] causes pruning to fail. + */ +SEC("socket") +__success __log_level(2) +__msg("8: (79) r1 = *(u64 *)(r10 -8)") +__msg("8: safe") +__msg("processed 11 insns") +__flag(BPF_F_TEST_STATE_FREQ) +__naked void old_imprecise_scalar32_vs_cur_stack_misc(void) +{ + asm volatile( + /* get a random value for branching */ + "call %[bpf_ktime_get_ns];" + "if r0 == 0 goto 1f;" + /* conjure 32-bit scalar spill at fp-8 */ + "r0 = 42;" + "*(u32*)(r10 - 8) = r0;" + "goto 2f;" +"1:" + /* conjure STACK_MISC at fp-8 */ + "call %[bpf_ktime_get_ns];" + "*(u16*)(r10 - 8) = r0;" + "*(u16*)(r10 - 6) = r0;" +"2:" + /* read fp-8, should be considered safe on second visit */ + "r1 = *(u64*)(r10 - 8);" + "exit;" + : + : __imm(bpf_ktime_get_ns) + : __clobber_all); +} + char _license[] SEC("license") = "GPL";