[PATCH bpf-next v2 22/22] selftests/bpf: Cover a backward may_goto pushed out of range by patches
From: Qiliang Yuan
Date: Fri Oct 30 2026 - 08:02:38 EST
bpf_do_misc_fixups() expands a backward may_goto to gotol when the
patches queued between it and its target push its offset out of the
16-bit range.
No test covers a backward may_goto whose expanded jump only goes out
of the 16-bit range through the patches in between.
Check that a may_goto jumping back over 8191 guarded divisions loads
and is expanded to gotol.
Signed-off-by: Qiliang Yuan <odys.yuan@xxxxxxxxx>
---
.../selftests/bpf/progs/verifier_patch_list.c | 35 ++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/tools/testing/selftests/bpf/progs/verifier_patch_list.c b/tools/testing/selftests/bpf/progs/verifier_patch_list.c
index 1370cdd5e5836..302e739caf83c 100644
--- a/tools/testing/selftests/bpf/progs/verifier_patch_list.c
+++ b/tools/testing/selftests/bpf/progs/verifier_patch_list.c
@@ -172,4 +172,39 @@ l0_%=: \
}
#endif
+/*
+ * may_goto jumps back by 8195 insns, by 32768 once each of the 8191
+ * divisions is guarded by a patch of 4 insns. That still fits the 16 bits of
+ * may_goto, but not the jump it expands to, which has to become gotol. Once
+ * the budget runs out, may_goto jumps back with r6 set and the program exits.
+ */
+SEC("raw_tp")
+__description("patch list: backward may_goto expanded to gotol")
+__arch_x86_64
+__success
+__xlated("...")
+__xlated("{{[0-9]+}}: gotol pc-{{[0-9]+}}")
+__naked void patch_list_may_goto_gotol(void)
+{
+ asm volatile (" \
+ call %[bpf_get_prandom_u32]; \
+ r1 = r0; \
+ r6 = 0; \
+ goto 0f; \
+1: r0 = 0; \
+ exit; \
+0: if r6 != 0 goto 1b; \
+ .rept 8191; \
+ r0 /= r1; \
+ .endr; \
+ r2 = 0; \
+ r6 = 1; \
+ may_goto 0b; \
+ r0 = 0; \
+ exit; \
+" :
+ : __imm(bpf_get_prandom_u32)
+ : __clobber_all);
+}
+
char _license[] SEC("license") = "GPL";
--
2.43.0