From 070587848985efcfcd45104c5266ba76a1165f55 Mon Sep 17 00:00:00 2001 From: Kumar Kartikeya Dwivedi Date: Sat, 19 Sep 2026 03:42:11 +0200 Subject: [PATCH] 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 Signed-off-by: Alexei Starovoitov Tested-by: Eduard Zingerman Link: https://patch.msgid.link/20260919014213.1840880-3-memxor@gmail.com --- .../selftests/bpf/progs/verifier_loops1.c | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_loops1.c b/tools/testing/selftests/bpf/progs/verifier_loops1.c index d248ce877f14..48a966cda199 100644 --- a/tools/testing/selftests/bpf/progs/verifier_loops1.c +++ b/tools/testing/selftests/bpf/progs/verifier_loops1.c @@ -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";