summaryrefslogtreecommitdiff
path: root/tools/testing
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2026-10-27 19:03:03 +0000
committerAlexei Starovoitov <ast@kernel.org>2026-10-28 04:07:03 +0000
commit165115760433adf29c76190db5ecfe781d6c9221 (patch)
treef2bb2a2b32bfd865968d0e60e8c4b4354905f422 /tools/testing
parent3f9924747c4422176346c34b5dff44ba8bca5180 (diff)
selftests/bpf: Test that a widened register is not linked
Scalar evolution widens a register that has delta 4. Then the prog copies the register. With the stale delta the verifier finds that a read of uninitialized r9 is dead code, and it loads the prog. See "bpf: Clear delta of a register that scalar evolution widens". Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261027190314.1440199-9-alexei.starovoitov@gmail.com
Diffstat (limited to 'tools/testing')
-rw-r--r--tools/testing/selftests/bpf/progs/verifier_scev.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/progs/verifier_scev.c b/tools/testing/selftests/bpf/progs/verifier_scev.c
index 37434efd1490..ddc9667bb078 100644
--- a/tools/testing/selftests/bpf/progs/verifier_scev.c
+++ b/tools/testing/selftests/bpf/progs/verifier_scev.c
@@ -1377,6 +1377,40 @@ __naked __noinline __used static int probe_read_stack(void)
: __clobber_all);
}
+/*
+ * r3 = r8 + 4 is linked to r8 when it enters the loop. Widening drops the link. If
+ * it leaves the 4 behind then r4 = r3 + 1 is taken for r3 - 3 when r3 is compared:
+ * r4 <= 7 instead of r4 <= 11, and the read of r9 looks like dead code.
+ */
+SEC("socket")
+__failure __msg("R9 !read_ok")
+__naked void widened_reg_is_not_linked(void)
+{
+ asm volatile (
+ "call %[bpf_get_prandom_u32];"
+ "r8 = r0;"
+ "r8 &= 0xff;"
+ "r3 = r8;"
+ "r3 += 4;"
+ "r1 = 0;"
+"1:"
+ "r4 = r3;"
+ "r4 += 1;"
+ "if r3 > 10 goto 3f;"
+ "if r4 <= 7 goto 2f;"
+ "r0 = *(u64 *)(r9 + 0);"
+"2:"
+ "r3 += 1;"
+ "r1 += 1;"
+ "if r1 < 2 goto 1b;"
+"3:"
+ "r0 = r8;"
+ "exit;"
+ :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
/* The unknown SCEV of an unbound STACK_MISC slot must not prevent widening. */
SEC("tracepoint")
__success