[PATCH 2/2] selftests/bpf: Test non-fetch atomic on a narrow stack spill
From: Hao Sun
Date: Thu Sep 24 2026 - 09:16:46 EST
Spill a 32-bit scalar into an 8-byte stack slot, leaving the other half
of the slot uninitialized, and apply a non-fetch 64-bit atomic add to the
slot. With CAP_BPF but without CAP_PERFMON the verifier rejects it.
Signed-off-by: Hao Sun <sunhao.th@xxxxxxxxx>
---
.../selftests/bpf/progs/verifier_spill_fill.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
index 39a1766dae3f..d9a4164b6685 100644
--- a/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
+++ b/tools/testing/selftests/bpf/progs/verifier_spill_fill.c
@@ -1344,6 +1344,23 @@ __naked void old_imprecise_scalar32_vs_cur_stack_misc(void)
: __clobber_all);
}
+SEC("socket")
+__description("stack_noperfmon: reject non-fetch atomic on narrow spill")
+__success
+__caps_unpriv(CAP_BPF)
+__failure_unpriv __msg_unpriv("invalid read from stack off -8+4 size 8")
+__naked void stack_noperfmon_reject_atomic_on_narrow_spill(void)
+{
+ asm volatile (
+ "r1 = 1;"
+ "*(u32 *)(r10 - 8) = r1;"
+ /* A non-fetch atomic reads all 8 bytes of the slot. */
+ "lock *(u64 *)(r10 - 8) += r1;"
+ "r0 = 0;"
+ "exit;"
+ ::: __clobber_all);
+}
+
SEC("raw_tp")
__success
__naked void var_off_write_over_scalar_spill(void)
--
2.34.1