selftests/bpf: Fix erroneous bitmask operation
[platform/kernel/linux-rpi.git] / tools / testing / selftests / bpf / progs / verifier_loops1.c
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("socket")
79 __description("bounded loop, start in the middle")
80 __success
81 __failure_unpriv __msg_unpriv("back-edge")
82 __naked void loop_start_in_the_middle(void)
83 {
84         asm volatile ("                                 \
85         r0 = 0;                                         \
86         goto l0_%=;                                     \
87 l1_%=:  r0 += 1;                                        \
88 l0_%=:  if r0 < 4 goto l1_%=;                           \
89         exit;                                           \
90 "       ::: __clobber_all);
91 }
92
93 SEC("xdp")
94 __description("bounded loop containing a forward jump")
95 __success __retval(4)
96 __naked void loop_containing_a_forward_jump(void)
97 {
98         asm volatile ("                                 \
99         r0 = 0;                                         \
100 l1_%=:  r0 += 1;                                        \
101         if r0 == r0 goto l0_%=;                         \
102 l0_%=:  if r0 < 4 goto l1_%=;                           \
103         exit;                                           \
104 "       ::: __clobber_all);
105 }
106
107 SEC("tracepoint")
108 __description("bounded loop that jumps out rather than in")
109 __success
110 __naked void jumps_out_rather_than_in(void)
111 {
112         asm volatile ("                                 \
113         r6 = 0;                                         \
114 l1_%=:  r6 += 1;                                        \
115         if r6 > 10000 goto l0_%=;                       \
116         call %[bpf_get_prandom_u32];                    \
117         goto l1_%=;                                     \
118 l0_%=:  exit;                                           \
119 "       :
120         : __imm(bpf_get_prandom_u32)
121         : __clobber_all);
122 }
123
124 SEC("tracepoint")
125 __description("infinite loop after a conditional jump")
126 __failure __msg("program is too large")
127 __naked void loop_after_a_conditional_jump(void)
128 {
129         asm volatile ("                                 \
130         r0 = 5;                                         \
131         if r0 < 4 goto l0_%=;                           \
132 l1_%=:  r0 += 1;                                        \
133         goto l1_%=;                                     \
134 l0_%=:  exit;                                           \
135 "       ::: __clobber_all);
136 }
137
138 SEC("tracepoint")
139 __description("bounded recursion")
140 __failure
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)
144 {
145         asm volatile ("                                 \
146         r1 = 0;                                         \
147         call bounded_recursion__1;                      \
148         exit;                                           \
149 "       ::: __clobber_all);
150 }
151
152 static __naked __noinline __attribute__((used))
153 void bounded_recursion__1(void)
154 {
155         asm volatile ("                                 \
156         r1 += 1;                                        \
157         r0 = r1;                                        \
158         if r1 < 4 goto l0_%=;                           \
159         exit;                                           \
160 l0_%=:  call bounded_recursion__1;                      \
161         exit;                                           \
162 "       ::: __clobber_all);
163 }
164
165 SEC("tracepoint")
166 __description("infinite loop in two jumps")
167 __failure __msg("loop detected")
168 __naked void infinite_loop_in_two_jumps(void)
169 {
170         asm volatile ("                                 \
171         r0 = 0;                                         \
172 l1_%=:  goto l0_%=;                                     \
173 l0_%=:  if r0 < 4 goto l1_%=;                           \
174         exit;                                           \
175 "       ::: __clobber_all);
176 }
177
178 SEC("tracepoint")
179 __description("infinite loop: three-jump trick")
180 __failure __msg("loop detected")
181 __naked void infinite_loop_three_jump_trick(void)
182 {
183         asm volatile ("                                 \
184         r0 = 0;                                         \
185 l2_%=:  r0 += 1;                                        \
186         r0 &= 1;                                        \
187         if r0 < 2 goto l0_%=;                           \
188         exit;                                           \
189 l0_%=:  r0 += 1;                                        \
190         r0 &= 1;                                        \
191         if r0 < 2 goto l1_%=;                           \
192         exit;                                           \
193 l1_%=:  r0 += 1;                                        \
194         r0 &= 1;                                        \
195         if r0 < 2 goto l2_%=;                           \
196         exit;                                           \
197 "       ::: __clobber_all);
198 }
199
200 SEC("xdp")
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)
204 {
205         asm volatile ("                                 \
206 l0_%=:  r0 = 123;                                       \
207         if r0 == 4 goto l0_%=;                          \
208         exit;                                           \
209 "       ::: __clobber_all);
210 }
211
212 SEC("xdp")
213 __description("taken loop with back jump to 1st insn")
214 __success __retval(55)
215 __naked void back_jump_to_1st_insn_2(void)
216 {
217         asm volatile ("                                 \
218         r1 = 10;                                        \
219         r2 = 0;                                         \
220         call back_jump_to_1st_insn_2__1;                \
221         exit;                                           \
222 "       ::: __clobber_all);
223 }
224
225 static __naked __noinline __attribute__((used))
226 void back_jump_to_1st_insn_2__1(void)
227 {
228         asm volatile ("                                 \
229 l0_%=:  r2 += r1;                                       \
230         r1 -= 1;                                        \
231         if r1 != 0 goto l0_%=;                          \
232         r0 = r2;                                        \
233         exit;                                           \
234 "       ::: __clobber_all);
235 }
236
237 SEC("xdp")
238 __description("taken loop with back jump to 1st insn, 2")
239 __success __retval(55)
240 __naked void jump_to_1st_insn_2(void)
241 {
242         asm volatile ("                                 \
243         r1 = 10;                                        \
244         r2 = 0;                                         \
245         call jump_to_1st_insn_2__1;                     \
246         exit;                                           \
247 "       ::: __clobber_all);
248 }
249
250 static __naked __noinline __attribute__((used))
251 void jump_to_1st_insn_2__1(void)
252 {
253         asm volatile ("                                 \
254 l0_%=:  r2 += r1;                                       \
255         r1 -= 1;                                        \
256         if w1 != 0 goto l0_%=;                          \
257         r0 = r2;                                        \
258         exit;                                           \
259 "       ::: __clobber_all);
260 }
261
262 char _license[] SEC("license") = "GPL";