Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2/* Converted from tools/testing/selftests/bpf/verifier/subreg.c */
3
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include "bpf_misc.h"
7
8/* This file contains sub-register zero extension checks for insns defining
9 * sub-registers, meaning:
10 * - All insns under BPF_ALU class. Their BPF_ALU32 variants or narrow width
11 * forms (BPF_END) could define sub-registers.
12 * - Narrow direct loads, BPF_B/H/W | BPF_LDX.
13 * - BPF_LD is not exposed to JIT back-ends, so no need for testing.
14 *
15 * "get_prandom_u32" is used to initialize low 32-bit of some registers to
16 * prevent potential optimizations done by verifier or JIT back-ends which could
17 * optimize register back into constant when range info shows one register is a
18 * constant.
19 */
20
21SEC("socket")
22__description("add32 reg zero extend check")
23__success __success_unpriv __retval(0)
24__naked void add32_reg_zero_extend_check(void)
25{
26 asm volatile (" \
27 call %[bpf_get_prandom_u32]; \
28 r1 = r0; \
29 r0 = 0x100000000 ll; \
30 w0 += w1; \
31 r0 >>= 32; \
32 exit; \
33" :
34 : __imm(bpf_get_prandom_u32)
35 : __clobber_all);
36}
37
38SEC("socket")
39__description("add32 imm zero extend check")
40__success __success_unpriv __retval(0)
41__naked void add32_imm_zero_extend_check(void)
42{
43 asm volatile (" \
44 call %[bpf_get_prandom_u32]; \
45 r1 = 0x1000000000 ll; \
46 r0 |= r1; \
47 /* An insn could have no effect on the low 32-bit, for example:\
48 * a = a + 0 \
49 * a = a | 0 \
50 * a = a & -1 \
51 * But, they should still zero high 32-bit. \
52 */ \
53 w0 += 0; \
54 r0 >>= 32; \
55 r6 = r0; \
56 call %[bpf_get_prandom_u32]; \
57 r1 = 0x1000000000 ll; \
58 r0 |= r1; \
59 w0 += -2; \
60 r0 >>= 32; \
61 r0 |= r6; \
62 exit; \
63" :
64 : __imm(bpf_get_prandom_u32)
65 : __clobber_all);
66}
67
68SEC("socket")
69__description("sub32 reg zero extend check")
70__success __success_unpriv __retval(0)
71__naked void sub32_reg_zero_extend_check(void)
72{
73 asm volatile (" \
74 call %[bpf_get_prandom_u32]; \
75 r1 = r0; \
76 r0 = 0x1ffffffff ll; \
77 w0 -= w1; \
78 r0 >>= 32; \
79 exit; \
80" :
81 : __imm(bpf_get_prandom_u32)
82 : __clobber_all);
83}
84
85SEC("socket")
86__description("sub32 imm zero extend check")
87__success __success_unpriv __retval(0)
88__naked void sub32_imm_zero_extend_check(void)
89{
90 asm volatile (" \
91 call %[bpf_get_prandom_u32]; \
92 r1 = 0x1000000000 ll; \
93 r0 |= r1; \
94 w0 -= 0; \
95 r0 >>= 32; \
96 r6 = r0; \
97 call %[bpf_get_prandom_u32]; \
98 r1 = 0x1000000000 ll; \
99 r0 |= r1; \
100 w0 -= 1; \
101 r0 >>= 32; \
102 r0 |= r6; \
103 exit; \
104" :
105 : __imm(bpf_get_prandom_u32)
106 : __clobber_all);
107}
108
109SEC("socket")
110__description("mul32 reg zero extend check")
111__success __success_unpriv __retval(0)
112__naked void mul32_reg_zero_extend_check(void)
113{
114 asm volatile (" \
115 call %[bpf_get_prandom_u32]; \
116 r1 = r0; \
117 r0 = 0x100000001 ll; \
118 w0 *= w1; \
119 r0 >>= 32; \
120 exit; \
121" :
122 : __imm(bpf_get_prandom_u32)
123 : __clobber_all);
124}
125
126SEC("socket")
127__description("mul32 imm zero extend check")
128__success __success_unpriv __retval(0)
129__naked void mul32_imm_zero_extend_check(void)
130{
131 asm volatile (" \
132 call %[bpf_get_prandom_u32]; \
133 r1 = 0x1000000000 ll; \
134 r0 |= r1; \
135 w0 *= 1; \
136 r0 >>= 32; \
137 r6 = r0; \
138 call %[bpf_get_prandom_u32]; \
139 r1 = 0x1000000000 ll; \
140 r0 |= r1; \
141 w0 *= -1; \
142 r0 >>= 32; \
143 r0 |= r6; \
144 exit; \
145" :
146 : __imm(bpf_get_prandom_u32)
147 : __clobber_all);
148}
149
150SEC("socket")
151__description("div32 reg zero extend check")
152__success __success_unpriv __retval(0)
153__naked void div32_reg_zero_extend_check(void)
154{
155 asm volatile (" \
156 call %[bpf_get_prandom_u32]; \
157 r1 = r0; \
158 r0 = -1; \
159 w0 /= w1; \
160 r0 >>= 32; \
161 exit; \
162" :
163 : __imm(bpf_get_prandom_u32)
164 : __clobber_all);
165}
166
167SEC("socket")
168__description("div32 imm zero extend check")
169__success __success_unpriv __retval(0)
170__naked void div32_imm_zero_extend_check(void)
171{
172 asm volatile (" \
173 call %[bpf_get_prandom_u32]; \
174 r1 = 0x1000000000 ll; \
175 r0 |= r1; \
176 w0 /= 1; \
177 r0 >>= 32; \
178 r6 = r0; \
179 call %[bpf_get_prandom_u32]; \
180 r1 = 0x1000000000 ll; \
181 r0 |= r1; \
182 w0 /= 2; \
183 r0 >>= 32; \
184 r0 |= r6; \
185 exit; \
186" :
187 : __imm(bpf_get_prandom_u32)
188 : __clobber_all);
189}
190
191SEC("socket")
192__description("or32 reg zero extend check")
193__success __success_unpriv __retval(0)
194__naked void or32_reg_zero_extend_check(void)
195{
196 asm volatile (" \
197 call %[bpf_get_prandom_u32]; \
198 r1 = r0; \
199 r0 = 0x100000001 ll; \
200 w0 |= w1; \
201 r0 >>= 32; \
202 exit; \
203" :
204 : __imm(bpf_get_prandom_u32)
205 : __clobber_all);
206}
207
208SEC("socket")
209__description("or32 imm zero extend check")
210__success __success_unpriv __retval(0)
211__naked void or32_imm_zero_extend_check(void)
212{
213 asm volatile (" \
214 call %[bpf_get_prandom_u32]; \
215 r1 = 0x1000000000 ll; \
216 r0 |= r1; \
217 w0 |= 0; \
218 r0 >>= 32; \
219 r6 = r0; \
220 call %[bpf_get_prandom_u32]; \
221 r1 = 0x1000000000 ll; \
222 r0 |= r1; \
223 w0 |= 1; \
224 r0 >>= 32; \
225 r0 |= r6; \
226 exit; \
227" :
228 : __imm(bpf_get_prandom_u32)
229 : __clobber_all);
230}
231
232SEC("socket")
233__description("and32 reg zero extend check")
234__success __success_unpriv __retval(0)
235__naked void and32_reg_zero_extend_check(void)
236{
237 asm volatile (" \
238 call %[bpf_get_prandom_u32]; \
239 r1 = 0x100000000 ll; \
240 r1 |= r0; \
241 r0 = 0x1ffffffff ll; \
242 w0 &= w1; \
243 r0 >>= 32; \
244 exit; \
245" :
246 : __imm(bpf_get_prandom_u32)
247 : __clobber_all);
248}
249
250SEC("socket")
251__description("and32 imm zero extend check")
252__success __success_unpriv __retval(0)
253__naked void and32_imm_zero_extend_check(void)
254{
255 asm volatile (" \
256 call %[bpf_get_prandom_u32]; \
257 r1 = 0x1000000000 ll; \
258 r0 |= r1; \
259 w0 &= -1; \
260 r0 >>= 32; \
261 r6 = r0; \
262 call %[bpf_get_prandom_u32]; \
263 r1 = 0x1000000000 ll; \
264 r0 |= r1; \
265 w0 &= -2; \
266 r0 >>= 32; \
267 r0 |= r6; \
268 exit; \
269" :
270 : __imm(bpf_get_prandom_u32)
271 : __clobber_all);
272}
273
274SEC("socket")
275__description("lsh32 reg zero extend check")
276__success __success_unpriv __retval(0)
277__naked void lsh32_reg_zero_extend_check(void)
278{
279 asm volatile (" \
280 call %[bpf_get_prandom_u32]; \
281 r1 = 0x100000000 ll; \
282 r0 |= r1; \
283 r1 = 1; \
284 w0 <<= w1; \
285 r0 >>= 32; \
286 exit; \
287" :
288 : __imm(bpf_get_prandom_u32)
289 : __clobber_all);
290}
291
292SEC("socket")
293__description("lsh32 imm zero extend check")
294__success __success_unpriv __retval(0)
295__naked void lsh32_imm_zero_extend_check(void)
296{
297 asm volatile (" \
298 call %[bpf_get_prandom_u32]; \
299 r1 = 0x1000000000 ll; \
300 r0 |= r1; \
301 w0 <<= 0; \
302 r0 >>= 32; \
303 r6 = r0; \
304 call %[bpf_get_prandom_u32]; \
305 r1 = 0x1000000000 ll; \
306 r0 |= r1; \
307 w0 <<= 1; \
308 r0 >>= 32; \
309 r0 |= r6; \
310 exit; \
311" :
312 : __imm(bpf_get_prandom_u32)
313 : __clobber_all);
314}
315
316SEC("socket")
317__description("rsh32 reg zero extend check")
318__success __success_unpriv __retval(0)
319__naked void rsh32_reg_zero_extend_check(void)
320{
321 asm volatile (" \
322 call %[bpf_get_prandom_u32]; \
323 r1 = 0x1000000000 ll; \
324 r0 |= r1; \
325 r1 = 1; \
326 w0 >>= w1; \
327 r0 >>= 32; \
328 exit; \
329" :
330 : __imm(bpf_get_prandom_u32)
331 : __clobber_all);
332}
333
334SEC("socket")
335__description("rsh32 imm zero extend check")
336__success __success_unpriv __retval(0)
337__naked void rsh32_imm_zero_extend_check(void)
338{
339 asm volatile (" \
340 call %[bpf_get_prandom_u32]; \
341 r1 = 0x1000000000 ll; \
342 r0 |= r1; \
343 w0 >>= 0; \
344 r0 >>= 32; \
345 r6 = r0; \
346 call %[bpf_get_prandom_u32]; \
347 r1 = 0x1000000000 ll; \
348 r0 |= r1; \
349 w0 >>= 1; \
350 r0 >>= 32; \
351 r0 |= r6; \
352 exit; \
353" :
354 : __imm(bpf_get_prandom_u32)
355 : __clobber_all);
356}
357
358SEC("socket")
359__description("neg32 reg zero extend check")
360__success __success_unpriv __retval(0)
361__naked void neg32_reg_zero_extend_check(void)
362{
363 asm volatile (" \
364 call %[bpf_get_prandom_u32]; \
365 r1 = 0x1000000000 ll; \
366 r0 |= r1; \
367 w0 = -w0; \
368 r0 >>= 32; \
369 exit; \
370" :
371 : __imm(bpf_get_prandom_u32)
372 : __clobber_all);
373}
374
375SEC("socket")
376__description("mod32 reg zero extend check")
377__success __success_unpriv __retval(0)
378__naked void mod32_reg_zero_extend_check(void)
379{
380 asm volatile (" \
381 call %[bpf_get_prandom_u32]; \
382 r1 = r0; \
383 r0 = -1; \
384 w0 %%= w1; \
385 r0 >>= 32; \
386 exit; \
387" :
388 : __imm(bpf_get_prandom_u32)
389 : __clobber_all);
390}
391
392SEC("socket")
393__description("mod32 imm zero extend check")
394__success __success_unpriv __retval(0)
395__naked void mod32_imm_zero_extend_check(void)
396{
397 asm volatile (" \
398 call %[bpf_get_prandom_u32]; \
399 r1 = 0x1000000000 ll; \
400 r0 |= r1; \
401 w0 %%= 1; \
402 r0 >>= 32; \
403 r6 = r0; \
404 call %[bpf_get_prandom_u32]; \
405 r1 = 0x1000000000 ll; \
406 r0 |= r1; \
407 w0 %%= 2; \
408 r0 >>= 32; \
409 r0 |= r6; \
410 exit; \
411" :
412 : __imm(bpf_get_prandom_u32)
413 : __clobber_all);
414}
415
416SEC("socket")
417__description("xor32 reg zero extend check")
418__success __success_unpriv __retval(0)
419__naked void xor32_reg_zero_extend_check(void)
420{
421 asm volatile (" \
422 call %[bpf_get_prandom_u32]; \
423 r1 = r0; \
424 r0 = 0x100000000 ll; \
425 w0 ^= w1; \
426 r0 >>= 32; \
427 exit; \
428" :
429 : __imm(bpf_get_prandom_u32)
430 : __clobber_all);
431}
432
433SEC("socket")
434__description("xor32 imm zero extend check")
435__success __success_unpriv __retval(0)
436__naked void xor32_imm_zero_extend_check(void)
437{
438 asm volatile (" \
439 call %[bpf_get_prandom_u32]; \
440 r1 = 0x1000000000 ll; \
441 r0 |= r1; \
442 w0 ^= 1; \
443 r0 >>= 32; \
444 exit; \
445" :
446 : __imm(bpf_get_prandom_u32)
447 : __clobber_all);
448}
449
450SEC("socket")
451__description("mov32 reg zero extend check")
452__success __success_unpriv __retval(0)
453__naked void mov32_reg_zero_extend_check(void)
454{
455 asm volatile (" \
456 call %[bpf_get_prandom_u32]; \
457 r1 = 0x100000000 ll; \
458 r1 |= r0; \
459 r0 = 0x100000000 ll; \
460 w0 = w1; \
461 r0 >>= 32; \
462 exit; \
463" :
464 : __imm(bpf_get_prandom_u32)
465 : __clobber_all);
466}
467
468SEC("socket")
469__description("mov32 imm zero extend check")
470__success __success_unpriv __retval(0)
471__naked void mov32_imm_zero_extend_check(void)
472{
473 asm volatile (" \
474 call %[bpf_get_prandom_u32]; \
475 r1 = 0x1000000000 ll; \
476 r0 |= r1; \
477 w0 = 0; \
478 r0 >>= 32; \
479 r6 = r0; \
480 call %[bpf_get_prandom_u32]; \
481 r1 = 0x1000000000 ll; \
482 r0 |= r1; \
483 w0 = 1; \
484 r0 >>= 32; \
485 r0 |= r6; \
486 exit; \
487" :
488 : __imm(bpf_get_prandom_u32)
489 : __clobber_all);
490}
491
492SEC("socket")
493__description("arsh32 reg zero extend check")
494__success __success_unpriv __retval(0)
495__naked void arsh32_reg_zero_extend_check(void)
496{
497 asm volatile (" \
498 call %[bpf_get_prandom_u32]; \
499 r1 = 0x1000000000 ll; \
500 r0 |= r1; \
501 r1 = 1; \
502 w0 s>>= w1; \
503 r0 >>= 32; \
504 exit; \
505" :
506 : __imm(bpf_get_prandom_u32)
507 : __clobber_all);
508}
509
510SEC("socket")
511__description("arsh32 imm zero extend check")
512__success __success_unpriv __retval(0)
513__naked void arsh32_imm_zero_extend_check(void)
514{
515 asm volatile (" \
516 call %[bpf_get_prandom_u32]; \
517 r1 = 0x1000000000 ll; \
518 r0 |= r1; \
519 w0 s>>= 0; \
520 r0 >>= 32; \
521 r6 = r0; \
522 call %[bpf_get_prandom_u32]; \
523 r1 = 0x1000000000 ll; \
524 r0 |= r1; \
525 w0 s>>= 1; \
526 r0 >>= 32; \
527 r0 |= r6; \
528 exit; \
529" :
530 : __imm(bpf_get_prandom_u32)
531 : __clobber_all);
532}
533
534SEC("socket")
535__description("arsh32 imm sign positive extend check")
536__success __retval(0)
537__log_level(2)
538__msg("2: (57) r6 &= 4095 ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=4095,var_off=(0x0; 0xfff))")
539__msg("3: (67) r6 <<= 32 ; R6=scalar(smin=smin32=0,smax=umax=0xfff00000000,smax32=umax32=0,var_off=(0x0; 0xfff00000000))")
540__msg("4: (c7) r6 s>>= 32 ; R6=scalar(smin=smin32=0,smax=umax=smax32=umax32=4095,var_off=(0x0; 0xfff))")
541__naked void arsh32_imm_sign_extend_positive_check(void)
542{
543 asm volatile (" \
544 call %[bpf_get_prandom_u32]; \
545 r6 = r0; \
546 r6 &= 4095; \
547 r6 <<= 32; \
548 r6 s>>= 32; \
549 r0 = 0; \
550 exit; \
551" :
552 : __imm(bpf_get_prandom_u32)
553 : __clobber_all);
554}
555
556SEC("socket")
557__description("arsh32 imm sign negative extend check")
558__success __retval(0)
559__log_level(2)
560__msg("3: (17) r6 -= 4095 ; R6=scalar(smin=smin32=-4095,smax=smax32=0)")
561__msg("4: (67) r6 <<= 32 ; R6=scalar(smin=0xfffff00100000000,smax=smax32=umax32=0,umax=0xffffffff00000000,smin32=0,var_off=(0x0; 0xffffffff00000000))")
562__msg("5: (c7) r6 s>>= 32 ; R6=scalar(smin=smin32=-4095,smax=smax32=0)")
563__naked void arsh32_imm_sign_extend_negative_check(void)
564{
565 asm volatile (" \
566 call %[bpf_get_prandom_u32]; \
567 r6 = r0; \
568 r6 &= 4095; \
569 r6 -= 4095; \
570 r6 <<= 32; \
571 r6 s>>= 32; \
572 r0 = 0; \
573 exit; \
574" :
575 : __imm(bpf_get_prandom_u32)
576 : __clobber_all);
577}
578
579SEC("socket")
580__description("arsh32 imm sign extend check")
581__success __retval(0)
582__log_level(2)
583__msg("3: (17) r6 -= 2047 ; R6=scalar(smin=smin32=-2047,smax=smax32=2048)")
584__msg("4: (67) r6 <<= 32 ; R6=scalar(smin=0xfffff80100000000,smax=0x80000000000,umax=0xffffffff00000000,smin32=0,smax32=umax32=0,var_off=(0x0; 0xffffffff00000000))")
585__msg("5: (c7) r6 s>>= 32 ; R6=scalar(smin=smin32=-2047,smax=smax32=2048)")
586__naked void arsh32_imm_sign_extend_check(void)
587{
588 asm volatile (" \
589 call %[bpf_get_prandom_u32]; \
590 r6 = r0; \
591 r6 &= 4095; \
592 r6 -= 2047; \
593 r6 <<= 32; \
594 r6 s>>= 32; \
595 r0 = 0; \
596 exit; \
597" :
598 : __imm(bpf_get_prandom_u32)
599 : __clobber_all);
600}
601
602SEC("socket")
603__description("end16 (to_le) reg zero extend check")
604__success __success_unpriv __retval(0)
605__naked void le_reg_zero_extend_check_1(void)
606{
607 asm volatile (" \
608 call %[bpf_get_prandom_u32]; \
609 r6 = r0; \
610 r6 <<= 32; \
611 call %[bpf_get_prandom_u32]; \
612 r0 |= r6; \
613 r0 = le16 r0; \
614 r0 >>= 32; \
615 exit; \
616" :
617 : __imm(bpf_get_prandom_u32)
618 : __clobber_all);
619}
620
621SEC("socket")
622__description("end32 (to_le) reg zero extend check")
623__success __success_unpriv __retval(0)
624__naked void le_reg_zero_extend_check_2(void)
625{
626 asm volatile (" \
627 call %[bpf_get_prandom_u32]; \
628 r6 = r0; \
629 r6 <<= 32; \
630 call %[bpf_get_prandom_u32]; \
631 r0 |= r6; \
632 r0 = le32 r0; \
633 r0 >>= 32; \
634 exit; \
635" :
636 : __imm(bpf_get_prandom_u32)
637 : __clobber_all);
638}
639
640SEC("socket")
641__description("end16 (to_be) reg zero extend check")
642__success __success_unpriv __retval(0)
643__naked void be_reg_zero_extend_check_1(void)
644{
645 asm volatile (" \
646 call %[bpf_get_prandom_u32]; \
647 r6 = r0; \
648 r6 <<= 32; \
649 call %[bpf_get_prandom_u32]; \
650 r0 |= r6; \
651 r0 = be16 r0; \
652 r0 >>= 32; \
653 exit; \
654" :
655 : __imm(bpf_get_prandom_u32)
656 : __clobber_all);
657}
658
659SEC("socket")
660__description("end32 (to_be) reg zero extend check")
661__success __success_unpriv __retval(0)
662__naked void be_reg_zero_extend_check_2(void)
663{
664 asm volatile (" \
665 call %[bpf_get_prandom_u32]; \
666 r6 = r0; \
667 r6 <<= 32; \
668 call %[bpf_get_prandom_u32]; \
669 r0 |= r6; \
670 r0 = be32 r0; \
671 r0 >>= 32; \
672 exit; \
673" :
674 : __imm(bpf_get_prandom_u32)
675 : __clobber_all);
676}
677
678SEC("socket")
679__description("ldx_b zero extend check")
680__success __success_unpriv __retval(0)
681__naked void ldx_b_zero_extend_check(void)
682{
683 asm volatile (" \
684 r6 = r10; \
685 r6 += -4; \
686 r7 = 0xfaceb00c; \
687 *(u32*)(r6 + 0) = r7; \
688 call %[bpf_get_prandom_u32]; \
689 r1 = 0x1000000000 ll; \
690 r0 |= r1; \
691 r0 = *(u8*)(r6 + 0); \
692 r0 >>= 32; \
693 exit; \
694" :
695 : __imm(bpf_get_prandom_u32)
696 : __clobber_all);
697}
698
699SEC("socket")
700__description("ldx_h zero extend check")
701__success __success_unpriv __retval(0)
702__naked void ldx_h_zero_extend_check(void)
703{
704 asm volatile (" \
705 r6 = r10; \
706 r6 += -4; \
707 r7 = 0xfaceb00c; \
708 *(u32*)(r6 + 0) = r7; \
709 call %[bpf_get_prandom_u32]; \
710 r1 = 0x1000000000 ll; \
711 r0 |= r1; \
712 r0 = *(u16*)(r6 + 0); \
713 r0 >>= 32; \
714 exit; \
715" :
716 : __imm(bpf_get_prandom_u32)
717 : __clobber_all);
718}
719
720SEC("socket")
721__description("ldx_w zero extend check")
722__success __success_unpriv __retval(0)
723__naked void ldx_w_zero_extend_check(void)
724{
725 asm volatile (" \
726 r6 = r10; \
727 r6 += -4; \
728 r7 = 0xfaceb00c; \
729 *(u32*)(r6 + 0) = r7; \
730 call %[bpf_get_prandom_u32]; \
731 r1 = 0x1000000000 ll; \
732 r0 |= r1; \
733 r0 = *(u32*)(r6 + 0); \
734 r0 >>= 32; \
735 exit; \
736" :
737 : __imm(bpf_get_prandom_u32)
738 : __clobber_all);
739}
740
741SEC("socket")
742__success __success_unpriv __retval(0)
743__naked void arsh_31_and(void)
744{
745 /* Below is what LLVM generates in cilium's bpf_wiregard.o */
746 asm volatile (" \
747 call %[bpf_get_prandom_u32]; \
748 w2 = w0; \
749 w2 s>>= 31; \
750 w2 &= -134; /* w2 becomes 0 or -134 */ \
751 if w2 s> -1 goto +2; \
752 /* Branch always taken because w2 = -134 */ \
753 if w2 != -136 goto +1; \
754 w0 /= 0; \
755 w0 = 0; \
756 exit; \
757" :
758 : __imm(bpf_get_prandom_u32)
759 : __clobber_all);
760}
761
762SEC("socket")
763__success __success_unpriv __retval(0)
764__naked void arsh_63_and(void)
765{
766 /* Copy of arsh_31 with s/w/r/ */
767 asm volatile (" \
768 call %[bpf_get_prandom_u32]; \
769 r2 = r0; \
770 r2 <<= 32; \
771 r2 s>>= 63; \
772 r2 &= -134; \
773 if r2 s> -1 goto +2; \
774 /* Branch always taken because w2 = -134 */ \
775 if r2 != -136 goto +1; \
776 r0 /= 0; \
777 r0 = 0; \
778 exit; \
779" :
780 : __imm(bpf_get_prandom_u32)
781 : __clobber_all);
782}
783
784SEC("socket")
785__success __success_unpriv __retval(0)
786__naked void arsh_31_or(void)
787{
788 asm volatile (" \
789 call %[bpf_get_prandom_u32]; \
790 w2 = w0; \
791 w2 s>>= 31; \
792 w2 |= 134; /* w2 becomes -1 or 134 */ \
793 if w2 s> -1 goto +2; \
794 /* Branch always taken because w2 = -1 */ \
795 if w2 == -1 goto +1; \
796 w0 /= 0; \
797 w0 = 0; \
798 exit; \
799" :
800 : __imm(bpf_get_prandom_u32)
801 : __clobber_all);
802}
803
804SEC("socket")
805__success __success_unpriv __retval(0)
806__naked void arsh_63_or(void)
807{
808 /* Copy of arsh_31 with s/w/r/ */
809 asm volatile (" \
810 call %[bpf_get_prandom_u32]; \
811 r2 = r0; \
812 r2 <<= 32; \
813 r2 s>>= 63; \
814 r2 |= 134; /* r2 becomes -1 or 134 */ \
815 if r2 s> -1 goto +2; \
816 /* Branch always taken because w2 = -1 */ \
817 if r2 == -1 goto +1; \
818 r0 /= 0; \
819 r0 = 0; \
820 exit; \
821" :
822 : __imm(bpf_get_prandom_u32)
823 : __clobber_all);
824}
825
826SEC("socket")
827__success __retval(42)
828__naked void arsh32_imm1_value(void)
829{
830 asm volatile (" \
831 r0 = 42; \
832 r1 = -2147483648; \
833 w1 s>>= 1; /* r1 = 0xC0000000 */ \
834 r2 = 0xC0000000 ll; \
835 if r1 == r2 goto l0_%=; \
836 r0 /= 0; /* unreachable */ \
837l0_%=: exit; \
838" :
839 :
840 : __clobber_all);
841}
842
843SEC("socket")
844__success __retval(1)
845__naked void lsh32_reg0_zero_extend_check(void)
846{
847 asm volatile (" \
848 r6 = 1; \
849 call %[bpf_get_prandom_u32]; \
850 r1 = 0x1000000000 ll; \
851 r0 |= r1; \
852 w1 = 0; \
853 w0 <<= w1; /* reg shift by 0 */ \
854 r0 >>= 32; /* must be 0 */ \
855 if r0 == 0 goto l0_%=; \
856 r6 /= 0; /* unreachable */ \
857l0_%=: r0 = r6; \
858 exit; \
859" :
860 : __imm(bpf_get_prandom_u32)
861 : __clobber_all);
862}
863
864SEC("socket")
865__success __retval(1)
866__naked void rsh32_reg0_zero_extend_check(void)
867{
868 asm volatile (" \
869 r6 = 1; \
870 call %[bpf_get_prandom_u32]; \
871 r1 = 0x1000000000 ll; \
872 r0 |= r1; \
873 w1 = 0; \
874 w0 >>= w1; /* reg rsh by 0 */ \
875 r0 >>= 32; /* must be 0 */ \
876 if r0 == 0 goto l0_%=; \
877 r6 /= 0; /* unreachable */ \
878l0_%=: r0 = r6; \
879 exit; \
880" :
881 : __imm(bpf_get_prandom_u32)
882 : __clobber_all);
883}
884
885SEC("socket")
886__success __retval(1)
887__naked void arsh32_reg0_zero_extend_check(void)
888{
889 asm volatile (" \
890 r6 = 1; \
891 call %[bpf_get_prandom_u32]; \
892 r1 = 0x1000000000 ll; \
893 r0 |= r1; \
894 w1 = 0; \
895 w0 s>>= w1; /* reg arsh by 0 */ \
896 r0 >>= 32; /* must be 0 */ \
897 if r0 == 0 goto l0_%=; \
898 r6 /= 0; /* unreachable */ \
899l0_%=: r0 = r6; \
900 exit; \
901" :
902 : __imm(bpf_get_prandom_u32)
903 : __clobber_all);
904}
905
906SEC("socket")
907__success __retval(42)
908__naked void lsh32_imm31_value(void)
909{
910 asm volatile (" \
911 r0 = 42; \
912 r1 = 1; \
913 w1 <<= 31; /* r1 = 0x80000000 */ \
914 r2 = 0x80000000 ll; \
915 if r1 == r2 goto l0_%=; \
916 r0 /= 0; /* unreachable */ \
917l0_%=: exit; \
918" :
919 :
920 : __clobber_all);
921}
922
923SEC("socket")
924__success __retval(42)
925__naked void rsh32_imm31_value(void)
926{
927 asm volatile (" \
928 r0 = 42; \
929 r1 = -2147483648; /* 0x80000000 */ \
930 w1 >>= 31; /* r1 = 1 */ \
931 if r1 == 1 goto l0_%=; \
932 r0 /= 0; /* unreachable */ \
933l0_%=: exit; \
934" :
935 :
936 : __clobber_all);
937}
938
939SEC("socket")
940__success __retval(42)
941__naked void arsh32_imm31_value(void)
942{
943 asm volatile (" \
944 r0 = 42; \
945 r1 = -2147483648; /* 0x80000000 */ \
946 w1 s>>= 31; /* r1 = 0xFFFFFFFF */ \
947 r2 = 0xFFFFFFFF ll; \
948 if r1 == r2 goto l0_%=; \
949 r0 /= 0; /* unreachable */ \
950l0_%=: exit; \
951" :
952 :
953 : __clobber_all);
954}
955
956SEC("socket")
957__success __retval(1)
958__naked void lsh32_unknown_precise_bounds(void)
959{
960 asm volatile (" \
961 r6 = 1; \
962 call %[bpf_get_prandom_u32]; \
963 w0 &= 3; /* u32: [0, 3] */ \
964 w0 <<= 1; /* u32: [0, 6] */ \
965 if w0 < 7 goto l0_%=; \
966 r6 /= 0; /* unreachable */ \
967l0_%=: r0 = r6; \
968 exit; \
969" :
970 : __imm(bpf_get_prandom_u32)
971 : __clobber_all);
972}
973
974SEC("socket")
975__success __retval(1)
976__naked void rsh32_unknown_bounds(void)
977{
978 asm volatile (" \
979 r6 = 1; \
980 call %[bpf_get_prandom_u32]; \
981 w0 >>= 28; /* u32: [0, 15] */ \
982 if w0 < 16 goto l0_%=; \
983 r6 /= 0; /* unreachable */ \
984l0_%=: r0 = r6; \
985 exit; \
986" :
987 : __imm(bpf_get_prandom_u32)
988 : __clobber_all);
989}
990
991char _license[] SEC("license") = "GPL";