Skip to content

Commit a6fc14d

Browse files
eddyz87Alexei Starovoitov
authored andcommitted
selftests/bpf: verifier/loops1 converted to inline assembly
Test verifier/loops1 automatically converted to use inline assembly. There are a few modifications for the converted tests. "tracepoint" programs do not support test execution, change program type to "xdp" (which supports test execution) for the following tests that have __retval tags: - bounded loop, count to 4 - bonded loop containing forward jump Also, remove the __retval tag for test: - bounded loop, count from positive unknown to 4 As it's return value is a random number. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> Link: https://lore.kernel.org/r/20230421174234.2391278-10-eddyz87@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
1 parent a5828e3 commit a6fc14d

3 files changed

Lines changed: 261 additions & 206 deletions

File tree

tools/testing/selftests/bpf/prog_tests/verifier.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "verifier_jeq_infer_not_null.skel.h"
3333
#include "verifier_ld_ind.skel.h"
3434
#include "verifier_leak_ptr.skel.h"
35+
#include "verifier_loops1.skel.h"
3536
#include "verifier_map_ptr.skel.h"
3637
#include "verifier_map_ret_val.skel.h"
3738
#include "verifier_masking.skel.h"
@@ -115,6 +116,7 @@ void test_verifier_int_ptr(void) { RUN(verifier_int_ptr); }
115116
void test_verifier_jeq_infer_not_null(void) { RUN(verifier_jeq_infer_not_null); }
116117
void test_verifier_ld_ind(void) { RUN(verifier_ld_ind); }
117118
void test_verifier_leak_ptr(void) { RUN(verifier_leak_ptr); }
119+
void test_verifier_loops1(void) { RUN(verifier_loops1); }
118120
void test_verifier_map_ptr(void) { RUN(verifier_map_ptr); }
119121
void test_verifier_map_ret_val(void) { RUN(verifier_map_ret_val); }
120122
void test_verifier_masking(void) { RUN(verifier_masking); }
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Converted from tools/testing/selftests/bpf/verifier/loops1.c */
3+
4+
#include <linux/bpf.h>
5+
#include <bpf/bpf_helpers.h>
6+
#include "bpf_misc.h"
7+
8+
SEC("xdp")
9+
__description("bounded loop, count to 4")
10+
__success __retval(4)
11+
__naked void bounded_loop_count_to_4(void)
12+
{
13+
asm volatile (" \
14+
r0 = 0; \
15+
l0_%=: r0 += 1; \
16+
if r0 < 4 goto l0_%=; \
17+
exit; \
18+
" ::: __clobber_all);
19+
}
20+
21+
SEC("tracepoint")
22+
__description("bounded loop, count to 20")
23+
__success
24+
__naked void bounded_loop_count_to_20(void)
25+
{
26+
asm volatile (" \
27+
r0 = 0; \
28+
l0_%=: r0 += 3; \
29+
if r0 < 20 goto l0_%=; \
30+
exit; \
31+
" ::: __clobber_all);
32+
}
33+
34+
SEC("tracepoint")
35+
__description("bounded loop, count from positive unknown to 4")
36+
__success
37+
__naked void from_positive_unknown_to_4(void)
38+
{
39+
asm volatile (" \
40+
call %[bpf_get_prandom_u32]; \
41+
if r0 s< 0 goto l0_%=; \
42+
l1_%=: r0 += 1; \
43+
if r0 < 4 goto l1_%=; \
44+
l0_%=: exit; \
45+
" :
46+
: __imm(bpf_get_prandom_u32)
47+
: __clobber_all);
48+
}
49+
50+
SEC("tracepoint")
51+
__description("bounded loop, count from totally unknown to 4")
52+
__success
53+
__naked void from_totally_unknown_to_4(void)
54+
{
55+
asm volatile (" \
56+
call %[bpf_get_prandom_u32]; \
57+
l0_%=: r0 += 1; \
58+
if r0 < 4 goto l0_%=; \
59+
exit; \
60+
" :
61+
: __imm(bpf_get_prandom_u32)
62+
: __clobber_all);
63+
}
64+
65+
SEC("tracepoint")
66+
__description("bounded loop, count to 4 with equality")
67+
__success
68+
__naked void count_to_4_with_equality(void)
69+
{
70+
asm volatile (" \
71+
r0 = 0; \
72+
l0_%=: r0 += 1; \
73+
if r0 != 4 goto l0_%=; \
74+
exit; \
75+
" ::: __clobber_all);
76+
}
77+
78+
SEC("tracepoint")
79+
__description("bounded loop, start in the middle")
80+
__failure __msg("back-edge")
81+
__naked void loop_start_in_the_middle(void)
82+
{
83+
asm volatile (" \
84+
r0 = 0; \
85+
goto l0_%=; \
86+
l1_%=: r0 += 1; \
87+
l0_%=: if r0 < 4 goto l1_%=; \
88+
exit; \
89+
" ::: __clobber_all);
90+
}
91+
92+
SEC("xdp")
93+
__description("bounded loop containing a forward jump")
94+
__success __retval(4)
95+
__naked void loop_containing_a_forward_jump(void)
96+
{
97+
asm volatile (" \
98+
r0 = 0; \
99+
l1_%=: r0 += 1; \
100+
if r0 == r0 goto l0_%=; \
101+
l0_%=: if r0 < 4 goto l1_%=; \
102+
exit; \
103+
" ::: __clobber_all);
104+
}
105+
106+
SEC("tracepoint")
107+
__description("bounded loop that jumps out rather than in")
108+
__success
109+
__naked void jumps_out_rather_than_in(void)
110+
{
111+
asm volatile (" \
112+
r6 = 0; \
113+
l1_%=: r6 += 1; \
114+
if r6 > 10000 goto l0_%=; \
115+
call %[bpf_get_prandom_u32]; \
116+
goto l1_%=; \
117+
l0_%=: exit; \
118+
" :
119+
: __imm(bpf_get_prandom_u32)
120+
: __clobber_all);
121+
}
122+
123+
SEC("tracepoint")
124+
__description("infinite loop after a conditional jump")
125+
__failure __msg("program is too large")
126+
__naked void loop_after_a_conditional_jump(void)
127+
{
128+
asm volatile (" \
129+
r0 = 5; \
130+
if r0 < 4 goto l0_%=; \
131+
l1_%=: r0 += 1; \
132+
goto l1_%=; \
133+
l0_%=: exit; \
134+
" ::: __clobber_all);
135+
}
136+
137+
SEC("tracepoint")
138+
__description("bounded recursion")
139+
__failure __msg("back-edge")
140+
__naked void bounded_recursion(void)
141+
{
142+
asm volatile (" \
143+
r1 = 0; \
144+
call bounded_recursion__1; \
145+
exit; \
146+
" ::: __clobber_all);
147+
}
148+
149+
static __naked __noinline __attribute__((used))
150+
void bounded_recursion__1(void)
151+
{
152+
asm volatile (" \
153+
r1 += 1; \
154+
r0 = r1; \
155+
if r1 < 4 goto l0_%=; \
156+
exit; \
157+
l0_%=: call bounded_recursion__1; \
158+
exit; \
159+
" ::: __clobber_all);
160+
}
161+
162+
SEC("tracepoint")
163+
__description("infinite loop in two jumps")
164+
__failure __msg("loop detected")
165+
__naked void infinite_loop_in_two_jumps(void)
166+
{
167+
asm volatile (" \
168+
r0 = 0; \
169+
l1_%=: goto l0_%=; \
170+
l0_%=: if r0 < 4 goto l1_%=; \
171+
exit; \
172+
" ::: __clobber_all);
173+
}
174+
175+
SEC("tracepoint")
176+
__description("infinite loop: three-jump trick")
177+
__failure __msg("loop detected")
178+
__naked void infinite_loop_three_jump_trick(void)
179+
{
180+
asm volatile (" \
181+
r0 = 0; \
182+
l2_%=: r0 += 1; \
183+
r0 &= 1; \
184+
if r0 < 2 goto l0_%=; \
185+
exit; \
186+
l0_%=: r0 += 1; \
187+
r0 &= 1; \
188+
if r0 < 2 goto l1_%=; \
189+
exit; \
190+
l1_%=: r0 += 1; \
191+
r0 &= 1; \
192+
if r0 < 2 goto l2_%=; \
193+
exit; \
194+
" ::: __clobber_all);
195+
}
196+
197+
SEC("xdp")
198+
__description("not-taken loop with back jump to 1st insn")
199+
__success __retval(123)
200+
__naked void back_jump_to_1st_insn_1(void)
201+
{
202+
asm volatile (" \
203+
l0_%=: r0 = 123; \
204+
if r0 == 4 goto l0_%=; \
205+
exit; \
206+
" ::: __clobber_all);
207+
}
208+
209+
SEC("xdp")
210+
__description("taken loop with back jump to 1st insn")
211+
__success __retval(55)
212+
__naked void back_jump_to_1st_insn_2(void)
213+
{
214+
asm volatile (" \
215+
r1 = 10; \
216+
r2 = 0; \
217+
call back_jump_to_1st_insn_2__1; \
218+
exit; \
219+
" ::: __clobber_all);
220+
}
221+
222+
static __naked __noinline __attribute__((used))
223+
void back_jump_to_1st_insn_2__1(void)
224+
{
225+
asm volatile (" \
226+
l0_%=: r2 += r1; \
227+
r1 -= 1; \
228+
if r1 != 0 goto l0_%=; \
229+
r0 = r2; \
230+
exit; \
231+
" ::: __clobber_all);
232+
}
233+
234+
SEC("xdp")
235+
__description("taken loop with back jump to 1st insn, 2")
236+
__success __retval(55)
237+
__naked void jump_to_1st_insn_2(void)
238+
{
239+
asm volatile (" \
240+
r1 = 10; \
241+
r2 = 0; \
242+
call jump_to_1st_insn_2__1; \
243+
exit; \
244+
" ::: __clobber_all);
245+
}
246+
247+
static __naked __noinline __attribute__((used))
248+
void jump_to_1st_insn_2__1(void)
249+
{
250+
asm volatile (" \
251+
l0_%=: r2 += r1; \
252+
r1 -= 1; \
253+
if w1 != 0 goto l0_%=; \
254+
r0 = r2; \
255+
exit; \
256+
" ::: __clobber_all);
257+
}
258+
259+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)