diff options
| author | Alexei Starovoitov <ast@kernel.org> | 2026-10-27 19:03:03 +0000 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-10-28 04:07:03 +0000 |
| commit | 165115760433adf29c76190db5ecfe781d6c9221 (patch) | |
| tree | f2bb2a2b32bfd865968d0e60e8c4b4354905f422 /tools/testing | |
| parent | 3f9924747c4422176346c34b5dff44ba8bca5180 (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.c | 34 |
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 |
