1 // SPDX-License-Identifier: GPL-2.0
2 /* Converted from tools/testing/selftests/bpf/verifier/loops1.c */
5 #include <bpf/bpf_helpers.h>
9 __description("bounded loop, count to 4")
11 __naked void bounded_loop_count_to_4(void)
16 if r0 < 4 goto l0_%=; \
22 __description("bounded loop, count to 20")
24 __naked void bounded_loop_count_to_20(void)
29 if r0 < 20 goto l0_%=; \
35 __description("bounded loop, count from positive unknown to 4")
37 __naked void from_positive_unknown_to_4(void)
40 call %[bpf_get_prandom_u32]; \
41 if r0 s< 0 goto l0_%=; \
43 if r0 < 4 goto l1_%=; \
46 : __imm(bpf_get_prandom_u32)
51 __description("bounded loop, count from totally unknown to 4")
53 __naked void from_totally_unknown_to_4(void)
56 call %[bpf_get_prandom_u32]; \
58 if r0 < 4 goto l0_%=; \
61 : __imm(bpf_get_prandom_u32)
66 __description("bounded loop, count to 4 with equality")
68 __naked void count_to_4_with_equality(void)
73 if r0 != 4 goto l0_%=; \
79 __description("bounded loop, start in the middle")
81 __failure_unpriv __msg_unpriv("back-edge")
82 __naked void loop_start_in_the_middle(void)
88 l0_%=: if r0 < 4 goto l1_%=; \
94 __description("bounded loop containing a forward jump")
96 __naked void loop_containing_a_forward_jump(void)
101 if r0 == r0 goto l0_%=; \
102 l0_%=: if r0 < 4 goto l1_%=; \
104 " ::: __clobber_all);
108 __description("bounded loop that jumps out rather than in")
110 __naked void jumps_out_rather_than_in(void)
115 if r6 > 10000 goto l0_%=; \
116 call %[bpf_get_prandom_u32]; \
120 : __imm(bpf_get_prandom_u32)
125 __description("infinite loop after a conditional jump")
126 __failure __msg("program is too large")
127 __naked void loop_after_a_conditional_jump(void)
131 if r0 < 4 goto l0_%=; \
135 " ::: __clobber_all);
139 __description("bounded recursion")
141 /* verifier limitation in detecting max stack depth */
142 __msg("the call stack of 8 frames is too deep !")
143 __naked void bounded_recursion(void)
147 call bounded_recursion__1; \
149 " ::: __clobber_all);
152 static __naked __noinline __attribute__((used))
153 void bounded_recursion__1(void)
158 if r1 < 4 goto l0_%=; \
160 l0_%=: call bounded_recursion__1; \
162 " ::: __clobber_all);
166 __description("infinite loop in two jumps")
167 __failure __msg("loop detected")
168 __naked void infinite_loop_in_two_jumps(void)
173 l0_%=: if r0 < 4 goto l1_%=; \
175 " ::: __clobber_all);
179 __description("infinite loop: three-jump trick")
180 __failure __msg("loop detected")
181 __naked void infinite_loop_three_jump_trick(void)
187 if r0 < 2 goto l0_%=; \
191 if r0 < 2 goto l1_%=; \
195 if r0 < 2 goto l2_%=; \
197 " ::: __clobber_all);
201 __description("not-taken loop with back jump to 1st insn")
202 __success __retval(123)
203 __naked void back_jump_to_1st_insn_1(void)
207 if r0 == 4 goto l0_%=; \
209 " ::: __clobber_all);
213 __description("taken loop with back jump to 1st insn")
214 __success __retval(55)
215 __naked void back_jump_to_1st_insn_2(void)
220 call back_jump_to_1st_insn_2__1; \
222 " ::: __clobber_all);
225 static __naked __noinline __attribute__((used))
226 void back_jump_to_1st_insn_2__1(void)
231 if r1 != 0 goto l0_%=; \
234 " ::: __clobber_all);
238 __description("taken loop with back jump to 1st insn, 2")
239 __success __retval(55)
240 __naked void jump_to_1st_insn_2(void)
245 call jump_to_1st_insn_2__1; \
247 " ::: __clobber_all);
250 static __naked __noinline __attribute__((used))
251 void jump_to_1st_insn_2__1(void)
256 if w1 != 0 goto l0_%=; \
259 " ::: __clobber_all);
262 char _license[] SEC("license") = "GPL";