[PATCH bpf 2/2] selftests/bpf: Cover stack nospec slot indexing

From: Nuoqi Gui

Date: Tue Jun 16 2026 - 13:11:26 EST


Add a verifier test for the fixed-offset stack write case where two 4-byte
stores initialize opposite halves of the same stack slot.

The test uses the CAP_BPF-without-CAP_PERFMON loader lane so Spectre v4
mitigation remains active. It expects both half-slot writes to emit nospec
in the translated program.

Signed-off-by: Nuoqi Gui <gnq25@xxxxxxxxxxxxxxxxxxxxx>
---
.../testing/selftests/bpf/progs/verifier_unpriv.c | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)

diff --git a/tools/testing/selftests/bpf/progs/verifier_unpriv.c b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
index c16f8382cf17d..9ebbd4b531df1 100644
--- a/tools/testing/selftests/bpf/progs/verifier_unpriv.c
+++ b/tools/testing/selftests/bpf/progs/verifier_unpriv.c
@@ -976,4 +976,27 @@ l0_%=: exit; \
: __clobber_all);
}

+SEC("socket")
+__description("noperfmon: Spectre v4 stack write slot index")
+__success __success_unpriv
+__caps_unpriv(CAP_BPF)
+__retval(0)
+#ifdef SPEC_V4
+__xlated_unpriv("r0 = 0")
+__xlated_unpriv("*(u32 *)(r10 -4) = r0")
+__xlated_unpriv("nospec")
+__xlated_unpriv("*(u32 *)(r10 -8) = r0")
+__xlated_unpriv("nospec")
+__xlated_unpriv("exit")
+#endif
+__naked void stack_write_nospec_slot_index(void)
+{
+ asm volatile (" \
+ r0 = 0; \
+ *(u32 *)(r10 - 4) = r0; \
+ *(u32 *)(r10 - 8) = r0; \
+ exit; \
+" ::: __clobber_all);
+}
+
char _license[] SEC("license") = "GPL";

--
2.34.1