selftests/bpf: Cover frame changes in bounded loops

Add a finite loop whose progress is represented only by changing the
frame number of a stack pointer. The loop first reads zero from the
caller's stack, switches to the same offset in the callee's stack, and
exits after reading one on its next iteration.

Force frequent checkpoints so the test exercises infinite-loop detection,
and check that the program returns one when run.

Without the frameno comparison in regs_exact(), the program is rejected
with an "infinite loop detected" diagnostic instead of loading
successfully.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://patch.msgid.link/20260919014213.1840880-3-memxor@gmail.com
This commit is contained in:
Kumar Kartikeya Dwivedi 2026-09-19 03:42:11 +02:00 committed by Alexei Starovoitov
parent 8901cee931
commit 0705878489
No known key found for this signature in database

View File

@ -303,4 +303,40 @@ __naked void maybe_exit_scc_bug1(void)
::: __clobber_all);
}
/*
* The loop reads zero from the caller's stack on its first iteration and
* one from the callee's stack on its second iteration. At the loop header,
* only the frame number of the pointer in r1 changes.
*/
static __naked __noinline __used
void loop_stack_frames_reg(void)
{
asm volatile (
"*(u64 *)(r10 - 8) = 1;"
"1:"
"r0 = *(u64 *)(r1 + 0);"
"if r0 != 0 goto 2f;"
"r1 = r10;"
"r1 += -8;"
"goto 1b;"
"2:"
"exit;"
::: __clobber_all);
}
SEC("xdp")
__description("bounded loop changing stack frame in a register")
__success __retval(1)
__flag(BPF_F_TEST_STATE_FREQ)
__naked void bounded_loop_stack_frames_reg(void)
{
asm volatile (
"*(u64 *)(r10 - 8) = 0;"
"r1 = r10;"
"r1 += -8;"
"call loop_stack_frames_reg;"
"exit;"
::: __clobber_all);
}
char _license[] SEC("license") = "GPL";