selftests/bpf: Test a loop that moves a pointer to a buffer

ptr_buf moves one pointer to a buffer until it gets to a second pointer. It
never reads through the pointer. It loads only if scalar evolution widens
the pointer, and that is no longer the case.

Change it to the loop that real progs have, for example
bpf_iter_bpf_percpu_array_map.c. It counts in a register and reads through
the pointer in each iteration. Without
"bpf: Don't widen a pointer to a buffer in scalar evolution" the verifier
rejects it with "invalid variable buffer offset".

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261027190314.1440199-13-alexei.starovoitov@gmail.com
This commit is contained in:
Alexei Starovoitov 2026-10-27 19:03:07 +00:00
parent 41750e5d68
commit 1b4ed112be
No known key found for this signature in database

View File

@ -3517,21 +3517,23 @@ __naked void ptr_mem_other_reservation(void)
: __clobber_all);
}
/* An access to a buffer at a variable offset is rejected: the pointer must not be widened. */
SEC("iter/bpf_map_elem")
__success
__log_level(2)
__flag(BPF_F_TEST_STATE_FREQ)
__msg("header_count is 4 ")
__msg("widening r6 to 0..3 step 1")
__msg("can't widen r6, expr is (+ r6 8)")
__naked void ptr_buf(void)
{
asm volatile (" \
r6 = *(u64 *)(r1 + %[value]); \
if r6 == 0 goto 2f; \
r7 = r6; \
r7 += 4; \
1: r6 += 1; \
if r6 < r7 goto 1b; \
r7 = 0; \
1: r0 = *(u32 *)(r6 + 0); \
r6 += 8; \
r7 += 1; \
if r7 < 4 goto 1b; \
2: r0 = 0; \
exit; \
" :