1// SPDX-License-Identifier: GPL-2.0
2/* Converted from tools/testing/selftests/bpf/verifier/value_ptr_arith.c */
3
4#include <linux/bpf.h>
5#include <bpf/bpf_helpers.h>
6#include <errno.h>
7#include "bpf_misc.h"
8
9#define MAX_ENTRIES 11
10
11struct test_val {
12 unsigned int index;
13 int foo[MAX_ENTRIES];
14};
15
16struct {
17 __uint(type, BPF_MAP_TYPE_ARRAY);
18 __uint(max_entries, 1);
19 __type(key, int);
20 __type(value, struct test_val);
21} map_array_48b SEC(".maps");
22
23struct other_val {
24 long long foo;
25 long long bar;
26};
27
28struct {
29 __uint(type, BPF_MAP_TYPE_HASH);
30 __uint(max_entries, 1);
31 __type(key, long long);
32 __type(value, struct other_val);
33} map_hash_16b SEC(".maps");
34
35struct {
36 __uint(type, BPF_MAP_TYPE_HASH);
37 __uint(max_entries, 1);
38 __type(key, long long);
39 __type(value, struct test_val);
40} map_hash_48b SEC(".maps");
41
42SEC("socket")
43__description("map access: known scalar += value_ptr unknown vs const")
44__success __failure_unpriv
45__msg_unpriv("R1 tried to add from different maps, paths or scalars")
46__retval(1)
47__naked void value_ptr_unknown_vs_const(void)
48{
49 asm volatile (" \
50 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
51 r1 = 0; \
52 *(u64*)(r10 - 8) = r1; \
53 r2 = r10; \
54 r2 += -8; \
55 if r0 == 1 goto l0_%=; \
56 r1 = %[map_hash_16b] ll; \
57 if r0 != 1 goto l1_%=; \
58l0_%=: r1 = %[map_array_48b] ll; \
59l1_%=: call %[bpf_map_lookup_elem]; \
60 if r0 == 0 goto l2_%=; \
61 r4 = *(u8*)(r0 + 0); \
62 if r4 == 1 goto l3_%=; \
63 r1 = 6; \
64 r1 = -r1; \
65 r1 &= 0x7; \
66 goto l4_%=; \
67l3_%=: r1 = 3; \
68l4_%=: r1 += r0; \
69 r0 = *(u8*)(r1 + 0); \
70l2_%=: r0 = 1; \
71 exit; \
72" :
73 : __imm(bpf_map_lookup_elem),
74 __imm_addr(map_array_48b),
75 __imm_addr(map_hash_16b),
76 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
77 : __clobber_all);
78}
79
80SEC("socket")
81__description("map access: known scalar += value_ptr const vs unknown")
82__success __failure_unpriv
83__msg_unpriv("R1 tried to add from different maps, paths or scalars")
84__retval(1)
85__naked void value_ptr_const_vs_unknown(void)
86{
87 asm volatile (" \
88 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
89 r1 = 0; \
90 *(u64*)(r10 - 8) = r1; \
91 r2 = r10; \
92 r2 += -8; \
93 if r0 == 1 goto l0_%=; \
94 r1 = %[map_hash_16b] ll; \
95 if r0 != 1 goto l1_%=; \
96l0_%=: r1 = %[map_array_48b] ll; \
97l1_%=: call %[bpf_map_lookup_elem]; \
98 if r0 == 0 goto l2_%=; \
99 r4 = *(u8*)(r0 + 0); \
100 if r4 == 1 goto l3_%=; \
101 r1 = 3; \
102 goto l4_%=; \
103l3_%=: r1 = 6; \
104 r1 = -r1; \
105 r1 &= 0x7; \
106l4_%=: r1 += r0; \
107 r0 = *(u8*)(r1 + 0); \
108l2_%=: r0 = 1; \
109 exit; \
110" :
111 : __imm(bpf_map_lookup_elem),
112 __imm_addr(map_array_48b),
113 __imm_addr(map_hash_16b),
114 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
115 : __clobber_all);
116}
117
118SEC("socket")
119__description("map access: known scalar += value_ptr const vs const (ne)")
120__success __failure_unpriv
121__msg_unpriv("R1 tried to add from different maps, paths or scalars")
122__retval(1)
123__naked void ptr_const_vs_const_ne(void)
124{
125 asm volatile (" \
126 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
127 r1 = 0; \
128 *(u64*)(r10 - 8) = r1; \
129 r2 = r10; \
130 r2 += -8; \
131 if r0 == 1 goto l0_%=; \
132 r1 = %[map_hash_16b] ll; \
133 if r0 != 1 goto l1_%=; \
134l0_%=: r1 = %[map_array_48b] ll; \
135l1_%=: call %[bpf_map_lookup_elem]; \
136 if r0 == 0 goto l2_%=; \
137 r4 = *(u8*)(r0 + 0); \
138 if r4 == 1 goto l3_%=; \
139 r1 = 3; \
140 goto l4_%=; \
141l3_%=: r1 = 5; \
142l4_%=: r1 += r0; \
143 r0 = *(u8*)(r1 + 0); \
144l2_%=: r0 = 1; \
145 exit; \
146" :
147 : __imm(bpf_map_lookup_elem),
148 __imm_addr(map_array_48b),
149 __imm_addr(map_hash_16b),
150 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
151 : __clobber_all);
152}
153
154SEC("socket")
155__description("map access: known scalar += value_ptr const vs const (eq)")
156__success __success_unpriv __retval(1)
157__naked void ptr_const_vs_const_eq(void)
158{
159 asm volatile (" \
160 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
161 r1 = 0; \
162 *(u64*)(r10 - 8) = r1; \
163 r2 = r10; \
164 r2 += -8; \
165 if r0 == 1 goto l0_%=; \
166 r1 = %[map_hash_16b] ll; \
167 if r0 != 1 goto l1_%=; \
168l0_%=: r1 = %[map_array_48b] ll; \
169l1_%=: call %[bpf_map_lookup_elem]; \
170 if r0 == 0 goto l2_%=; \
171 r4 = *(u8*)(r0 + 0); \
172 if r4 == 1 goto l3_%=; \
173 r1 = 5; \
174 goto l4_%=; \
175l3_%=: r1 = 5; \
176l4_%=: r1 += r0; \
177 r0 = *(u8*)(r1 + 0); \
178l2_%=: r0 = 1; \
179 exit; \
180" :
181 : __imm(bpf_map_lookup_elem),
182 __imm_addr(map_array_48b),
183 __imm_addr(map_hash_16b),
184 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
185 : __clobber_all);
186}
187
188SEC("socket")
189__description("map access: known scalar += value_ptr unknown vs unknown (eq)")
190__success __success_unpriv __retval(1)
191__naked void ptr_unknown_vs_unknown_eq(void)
192{
193 asm volatile (" \
194 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
195 r1 = 0; \
196 *(u64*)(r10 - 8) = r1; \
197 r2 = r10; \
198 r2 += -8; \
199 if r0 == 1 goto l0_%=; \
200 r1 = %[map_hash_16b] ll; \
201 if r0 != 1 goto l1_%=; \
202l0_%=: r1 = %[map_array_48b] ll; \
203l1_%=: call %[bpf_map_lookup_elem]; \
204 if r0 == 0 goto l2_%=; \
205 r4 = *(u8*)(r0 + 0); \
206 if r4 == 1 goto l3_%=; \
207 r1 = 6; \
208 r1 = -r1; \
209 r1 &= 0x7; \
210 goto l4_%=; \
211l3_%=: r1 = 6; \
212 r1 = -r1; \
213 r1 &= 0x7; \
214l4_%=: r1 += r0; \
215 r0 = *(u8*)(r1 + 0); \
216l2_%=: r0 = 1; \
217 exit; \
218" :
219 : __imm(bpf_map_lookup_elem),
220 __imm_addr(map_array_48b),
221 __imm_addr(map_hash_16b),
222 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
223 : __clobber_all);
224}
225
226SEC("socket")
227__description("map access: known scalar += value_ptr unknown vs unknown (lt)")
228__success __failure_unpriv
229__msg_unpriv("R1 tried to add from different maps, paths or scalars")
230__retval(1)
231__naked void ptr_unknown_vs_unknown_lt(void)
232{
233 asm volatile (" \
234 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
235 r1 = 0; \
236 *(u64*)(r10 - 8) = r1; \
237 r2 = r10; \
238 r2 += -8; \
239 if r0 == 1 goto l0_%=; \
240 r1 = %[map_hash_16b] ll; \
241 if r0 != 1 goto l1_%=; \
242l0_%=: r1 = %[map_array_48b] ll; \
243l1_%=: call %[bpf_map_lookup_elem]; \
244 if r0 == 0 goto l2_%=; \
245 r4 = *(u8*)(r0 + 0); \
246 if r4 == 1 goto l3_%=; \
247 r1 = 6; \
248 r1 = -r1; \
249 r1 &= 0x3; \
250 goto l4_%=; \
251l3_%=: r1 = 6; \
252 r1 = -r1; \
253 r1 &= 0x7; \
254l4_%=: r1 += r0; \
255 r0 = *(u8*)(r1 + 0); \
256l2_%=: r0 = 1; \
257 exit; \
258" :
259 : __imm(bpf_map_lookup_elem),
260 __imm_addr(map_array_48b),
261 __imm_addr(map_hash_16b),
262 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
263 : __clobber_all);
264}
265
266SEC("socket")
267__description("map access: known scalar += value_ptr unknown vs unknown (gt)")
268__success __failure_unpriv
269__msg_unpriv("R1 tried to add from different maps, paths or scalars")
270__retval(1)
271__naked void ptr_unknown_vs_unknown_gt(void)
272{
273 asm volatile (" \
274 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
275 r1 = 0; \
276 *(u64*)(r10 - 8) = r1; \
277 r2 = r10; \
278 r2 += -8; \
279 if r0 == 1 goto l0_%=; \
280 r1 = %[map_hash_16b] ll; \
281 if r0 != 1 goto l1_%=; \
282l0_%=: r1 = %[map_array_48b] ll; \
283l1_%=: call %[bpf_map_lookup_elem]; \
284 if r0 == 0 goto l2_%=; \
285 r4 = *(u8*)(r0 + 0); \
286 if r4 == 1 goto l3_%=; \
287 r1 = 6; \
288 r1 = -r1; \
289 r1 &= 0x7; \
290 goto l4_%=; \
291l3_%=: r1 = 6; \
292 r1 = -r1; \
293 r1 &= 0x3; \
294l4_%=: r1 += r0; \
295 r0 = *(u8*)(r1 + 0); \
296l2_%=: r0 = 1; \
297 exit; \
298" :
299 : __imm(bpf_map_lookup_elem),
300 __imm_addr(map_array_48b),
301 __imm_addr(map_hash_16b),
302 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
303 : __clobber_all);
304}
305
306SEC("socket")
307__description("map access: known scalar += value_ptr from different maps")
308__success __success_unpriv __retval(1)
309__naked void value_ptr_from_different_maps(void)
310{
311 asm volatile (" \
312 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
313 r1 = 0; \
314 *(u64*)(r10 - 8) = r1; \
315 r2 = r10; \
316 r2 += -8; \
317 if r0 == 1 goto l0_%=; \
318 r1 = %[map_hash_16b] ll; \
319 if r0 != 1 goto l1_%=; \
320l0_%=: r1 = %[map_array_48b] ll; \
321l1_%=: call %[bpf_map_lookup_elem]; \
322 if r0 == 0 goto l2_%=; \
323 r1 = 4; \
324 r1 += r0; \
325 r0 = *(u8*)(r1 + 0); \
326l2_%=: r0 = 1; \
327 exit; \
328" :
329 : __imm(bpf_map_lookup_elem),
330 __imm_addr(map_array_48b),
331 __imm_addr(map_hash_16b),
332 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
333 : __clobber_all);
334}
335
336SEC("socket")
337__description("map access: value_ptr -= known scalar from different maps")
338__success __failure_unpriv
339__msg_unpriv("R0 min value is outside of the allowed memory range")
340__retval(1)
341__naked void known_scalar_from_different_maps(void)
342{
343 asm volatile (" \
344 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
345 r1 = 0; \
346 *(u64*)(r10 - 8) = r1; \
347 r2 = r10; \
348 r2 += -8; \
349 if r0 == 1 goto l0_%=; \
350 r1 = %[map_hash_16b] ll; \
351 if r0 != 1 goto l1_%=; \
352l0_%=: r1 = %[map_array_48b] ll; \
353l1_%=: call %[bpf_map_lookup_elem]; \
354 if r0 == 0 goto l2_%=; \
355 r1 = 4; \
356 r0 -= r1; \
357 r0 += r1; \
358 r0 = *(u8*)(r0 + 0); \
359l2_%=: r0 = 1; \
360 exit; \
361" :
362 : __imm(bpf_map_lookup_elem),
363 __imm_addr(map_array_48b),
364 __imm_addr(map_hash_16b),
365 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
366 : __clobber_all);
367}
368
369SEC("socket")
370__description("map access: known scalar += value_ptr from different maps, but same value properties")
371__success __success_unpriv __retval(1)
372__naked void maps_but_same_value_properties(void)
373{
374 asm volatile (" \
375 r0 = *(u32*)(r1 + %[__sk_buff_len]); \
376 r1 = 0; \
377 *(u64*)(r10 - 8) = r1; \
378 r2 = r10; \
379 r2 += -8; \
380 if r0 == 1 goto l0_%=; \
381 r1 = %[map_hash_48b] ll; \
382 if r0 != 1 goto l1_%=; \
383l0_%=: r1 = %[map_array_48b] ll; \
384l1_%=: call %[bpf_map_lookup_elem]; \
385 if r0 == 0 goto l2_%=; \
386 r1 = 4; \
387 r1 += r0; \
388 r0 = *(u8*)(r1 + 0); \
389l2_%=: r0 = 1; \
390 exit; \
391" :
392 : __imm(bpf_map_lookup_elem),
393 __imm_addr(map_array_48b),
394 __imm_addr(map_hash_48b),
395 __imm_const(__sk_buff_len, offsetof(struct __sk_buff, len))
396 : __clobber_all);
397}
398
399SEC("socket")
400__description("map access: mixing value pointer and scalar, 1")
401__success __failure_unpriv __msg_unpriv("R2 pointer comparison prohibited")
402__retval(0)
403__naked void value_pointer_and_scalar_1(void)
404{
405 asm volatile (" \
406 /* load map value pointer into r0 and r2 */ \
407 r0 = 1; \
408 r1 = %[map_array_48b] ll; \
409 r2 = r10; \
410 r2 += -16; \
411 r6 = 0; \
412 *(u64*)(r10 - 16) = r6; \
413 call %[bpf_map_lookup_elem]; \
414 if r0 != 0 goto l0_%=; \
415 exit; \
416l0_%=: /* load some number from the map into r1 */ \
417 r1 = *(u8*)(r0 + 0); \
418 /* depending on r1, branch: */ \
419 if r1 != 0 goto l1_%=; \
420 /* branch A */ \
421 r2 = r0; \
422 r3 = 0; \
423 goto l2_%=; \
424l1_%=: /* branch B */ \
425 r2 = 0; \
426 r3 = 0x100000; \
427l2_%=: /* common instruction */ \
428 r2 += r3; \
429 /* depending on r1, branch: */ \
430 if r1 != 0 goto l3_%=; \
431 /* branch A */ \
432 goto l4_%=; \
433l3_%=: /* branch B */ \
434 r0 = 0x13371337; \
435 /* verifier follows fall-through */ \
436 if r2 != 0x100000 goto l4_%=; \
437 r0 = 0; \
438 exit; \
439l4_%=: /* fake-dead code; targeted from branch A to \
440 * prevent dead code sanitization \
441 */ \
442 r0 = *(u8*)(r0 + 0); \
443 r0 = 0; \
444 exit; \
445" :
446 : __imm(bpf_map_lookup_elem),
447 __imm_addr(map_array_48b)
448 : __clobber_all);
449}
450
451SEC("socket")
452__description("map access: mixing value pointer and scalar, 2")
453__success __failure_unpriv __msg_unpriv("R0 invalid mem access 'scalar'")
454__retval(0)
455__naked void value_pointer_and_scalar_2(void)
456{
457 asm volatile (" \
458 /* load map value pointer into r0 and r2 */ \
459 r0 = 1; \
460 r1 = %[map_array_48b] ll; \
461 r2 = r10; \
462 r2 += -16; \
463 r6 = 0; \
464 *(u64*)(r10 - 16) = r6; \
465 call %[bpf_map_lookup_elem]; \
466 if r0 != 0 goto l0_%=; \
467 exit; \
468l0_%=: /* load some number from the map into r1 */ \
469 r1 = *(u8*)(r0 + 0); \
470 /* depending on r1, branch: */ \
471 if r1 == 0 goto l1_%=; \
472 /* branch A */ \
473 r2 = 0; \
474 r3 = 0x100000; \
475 goto l2_%=; \
476l1_%=: /* branch B */ \
477 r2 = r0; \
478 r3 = 0; \
479l2_%=: /* common instruction */ \
480 r2 += r3; \
481 /* depending on r1, branch: */ \
482 if r1 != 0 goto l3_%=; \
483 /* branch A */ \
484 goto l4_%=; \
485l3_%=: /* branch B */ \
486 r0 = 0x13371337; \
487 /* verifier follows fall-through */ \
488 if r2 != 0x100000 goto l4_%=; \
489 r0 = 0; \
490 exit; \
491l4_%=: /* fake-dead code; targeted from branch A to \
492 * prevent dead code sanitization, rejected \
493 * via branch B however \
494 */ \
495 r0 = *(u8*)(r0 + 0); \
496 r0 = 0; \
497 exit; \
498" :
499 : __imm(bpf_map_lookup_elem),
500 __imm_addr(map_array_48b)
501 : __clobber_all);
502}
503
504SEC("socket")
505__description("sanitation: alu with different scalars 1")
506__success __success_unpriv __retval(0x100000)
507__naked void alu_with_different_scalars_1(void)
508{
509 asm volatile (" \
510 r0 = 1; \
511 r1 = %[map_array_48b] ll; \
512 r2 = r10; \
513 r2 += -16; \
514 r6 = 0; \
515 *(u64*)(r10 - 16) = r6; \
516 call %[bpf_map_lookup_elem]; \
517 if r0 != 0 goto l0_%=; \
518 exit; \
519l0_%=: r1 = *(u32*)(r0 + 0); \
520 if r1 == 0 goto l1_%=; \
521 r2 = 0; \
522 r3 = 0x100000; \
523 goto l2_%=; \
524l1_%=: r2 = 42; \
525 r3 = 0x100001; \
526l2_%=: r2 += r3; \
527 r0 = r2; \
528 exit; \
529" :
530 : __imm(bpf_map_lookup_elem),
531 __imm_addr(map_array_48b)
532 : __clobber_all);
533}
534
535SEC("socket")
536__description("sanitation: alu with different scalars 2")
537__success __success_unpriv __retval(0)
538__naked void alu_with_different_scalars_2(void)
539{
540 asm volatile (" \
541 r0 = 1; \
542 r1 = %[map_array_48b] ll; \
543 r6 = r1; \
544 r2 = r10; \
545 r2 += -16; \
546 r7 = 0; \
547 *(u64*)(r10 - 16) = r7; \
548 call %[bpf_map_delete_elem]; \
549 r7 = r0; \
550 r1 = r6; \
551 r2 = r10; \
552 r2 += -16; \
553 call %[bpf_map_delete_elem]; \
554 r6 = r0; \
555 r8 = r6; \
556 r8 += r7; \
557 r0 = r8; \
558 r0 += %[einval]; \
559 r0 += %[einval]; \
560 exit; \
561" :
562 : __imm(bpf_map_delete_elem),
563 __imm_addr(map_array_48b),
564 __imm_const(einval, EINVAL)
565 : __clobber_all);
566}
567
568SEC("socket")
569__description("sanitation: alu with different scalars 3")
570__success __success_unpriv __retval(0)
571__naked void alu_with_different_scalars_3(void)
572{
573 asm volatile (" \
574 r0 = %[einval]; \
575 r0 *= -1; \
576 r7 = r0; \
577 r0 = %[einval]; \
578 r0 *= -1; \
579 r6 = r0; \
580 r8 = r6; \
581 r8 += r7; \
582 r0 = r8; \
583 r0 += %[einval]; \
584 r0 += %[einval]; \
585 exit; \
586" :
587 : __imm_const(einval, EINVAL)
588 : __clobber_all);
589}
590
591SEC("socket")
592__description("map access: value_ptr += known scalar, upper oob arith, test 1")
593__success __failure_unpriv
594__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
595__retval(1)
596__naked void upper_oob_arith_test_1(void)
597{
598 asm volatile (" \
599 r1 = 0; \
600 *(u64*)(r10 - 8) = r1; \
601 r2 = r10; \
602 r2 += -8; \
603 r1 = %[map_array_48b] ll; \
604 call %[bpf_map_lookup_elem]; \
605 if r0 == 0 goto l0_%=; \
606 r1 = 48; \
607 r0 += r1; \
608 r0 -= r1; \
609 r0 = *(u8*)(r0 + 0); \
610l0_%=: r0 = 1; \
611 exit; \
612" :
613 : __imm(bpf_map_lookup_elem),
614 __imm_addr(map_array_48b)
615 : __clobber_all);
616}
617
618SEC("socket")
619__description("map access: value_ptr += known scalar, upper oob arith, test 2")
620__success __failure_unpriv
621__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
622__retval(1)
623__naked void upper_oob_arith_test_2(void)
624{
625 asm volatile (" \
626 r1 = 0; \
627 *(u64*)(r10 - 8) = r1; \
628 r2 = r10; \
629 r2 += -8; \
630 r1 = %[map_array_48b] ll; \
631 call %[bpf_map_lookup_elem]; \
632 if r0 == 0 goto l0_%=; \
633 r1 = 49; \
634 r0 += r1; \
635 r0 -= r1; \
636 r0 = *(u8*)(r0 + 0); \
637l0_%=: r0 = 1; \
638 exit; \
639" :
640 : __imm(bpf_map_lookup_elem),
641 __imm_addr(map_array_48b)
642 : __clobber_all);
643}
644
645SEC("socket")
646__description("map access: value_ptr += known scalar, upper oob arith, test 3")
647__success __success_unpriv __retval(1)
648__naked void upper_oob_arith_test_3(void)
649{
650 asm volatile (" \
651 r1 = 0; \
652 *(u64*)(r10 - 8) = r1; \
653 r2 = r10; \
654 r2 += -8; \
655 r1 = %[map_array_48b] ll; \
656 call %[bpf_map_lookup_elem]; \
657 if r0 == 0 goto l0_%=; \
658 r1 = 47; \
659 r0 += r1; \
660 r0 -= r1; \
661 r0 = *(u8*)(r0 + 0); \
662l0_%=: r0 = 1; \
663 exit; \
664" :
665 : __imm(bpf_map_lookup_elem),
666 __imm_addr(map_array_48b)
667 : __clobber_all);
668}
669
670SEC("socket")
671__description("map access: value_ptr -= known scalar, lower oob arith, test 1")
672__failure __msg("R0 min value is outside of the allowed memory range")
673__failure_unpriv
674__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
675__naked void lower_oob_arith_test_1(void)
676{
677 asm volatile (" \
678 r1 = 0; \
679 *(u64*)(r10 - 8) = r1; \
680 r2 = r10; \
681 r2 += -8; \
682 r1 = %[map_array_48b] ll; \
683 call %[bpf_map_lookup_elem]; \
684 if r0 == 0 goto l0_%=; \
685 r1 = 47; \
686 r0 += r1; \
687 r1 = 48; \
688 r0 -= r1; \
689 r0 = *(u8*)(r0 + 0); \
690l0_%=: r0 = 1; \
691 exit; \
692" :
693 : __imm(bpf_map_lookup_elem),
694 __imm_addr(map_array_48b)
695 : __clobber_all);
696}
697
698SEC("socket")
699__description("map access: value_ptr -= known scalar, lower oob arith, test 2")
700__success __failure_unpriv
701__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
702__retval(1)
703__naked void lower_oob_arith_test_2(void)
704{
705 asm volatile (" \
706 r1 = 0; \
707 *(u64*)(r10 - 8) = r1; \
708 r2 = r10; \
709 r2 += -8; \
710 r1 = %[map_array_48b] ll; \
711 call %[bpf_map_lookup_elem]; \
712 if r0 == 0 goto l0_%=; \
713 r1 = 47; \
714 r0 += r1; \
715 r1 = 48; \
716 r0 -= r1; \
717 r1 = 1; \
718 r0 += r1; \
719 r0 = *(u8*)(r0 + 0); \
720l0_%=: r0 = 1; \
721 exit; \
722" :
723 : __imm(bpf_map_lookup_elem),
724 __imm_addr(map_array_48b)
725 : __clobber_all);
726}
727
728SEC("socket")
729__description("map access: value_ptr -= known scalar, lower oob arith, test 3")
730__success __success_unpriv __retval(1)
731__naked void lower_oob_arith_test_3(void)
732{
733 asm volatile (" \
734 r1 = 0; \
735 *(u64*)(r10 - 8) = r1; \
736 r2 = r10; \
737 r2 += -8; \
738 r1 = %[map_array_48b] ll; \
739 call %[bpf_map_lookup_elem]; \
740 if r0 == 0 goto l0_%=; \
741 r1 = 47; \
742 r0 += r1; \
743 r1 = 47; \
744 r0 -= r1; \
745 r0 = *(u8*)(r0 + 0); \
746l0_%=: r0 = 1; \
747 exit; \
748" :
749 : __imm(bpf_map_lookup_elem),
750 __imm_addr(map_array_48b)
751 : __clobber_all);
752}
753
754SEC("socket")
755__description("map access: known scalar += value_ptr")
756__success __success_unpriv __retval(1)
757__naked void access_known_scalar_value_ptr_1(void)
758{
759 asm volatile (" \
760 r1 = 0; \
761 *(u64*)(r10 - 8) = r1; \
762 r2 = r10; \
763 r2 += -8; \
764 r1 = %[map_array_48b] ll; \
765 call %[bpf_map_lookup_elem]; \
766 if r0 == 0 goto l0_%=; \
767 r1 = 4; \
768 r1 += r0; \
769 r0 = *(u8*)(r1 + 0); \
770l0_%=: r0 = 1; \
771 exit; \
772" :
773 : __imm(bpf_map_lookup_elem),
774 __imm_addr(map_array_48b)
775 : __clobber_all);
776}
777
778SEC("socket")
779__description("map access: value_ptr += known scalar, 1")
780__success __success_unpriv __retval(1)
781__naked void value_ptr_known_scalar_1(void)
782{
783 asm volatile (" \
784 r1 = 0; \
785 *(u64*)(r10 - 8) = r1; \
786 r2 = r10; \
787 r2 += -8; \
788 r1 = %[map_array_48b] ll; \
789 call %[bpf_map_lookup_elem]; \
790 if r0 == 0 goto l0_%=; \
791 r1 = 4; \
792 r0 += r1; \
793 r1 = *(u8*)(r0 + 0); \
794l0_%=: r0 = 1; \
795 exit; \
796" :
797 : __imm(bpf_map_lookup_elem),
798 __imm_addr(map_array_48b)
799 : __clobber_all);
800}
801
802SEC("socket")
803__description("map access: value_ptr += known scalar, 2")
804__failure __msg("invalid access to map value")
805__failure_unpriv
806__naked void value_ptr_known_scalar_2_1(void)
807{
808 asm volatile (" \
809 r1 = 0; \
810 *(u64*)(r10 - 8) = r1; \
811 r2 = r10; \
812 r2 += -8; \
813 r1 = %[map_array_48b] ll; \
814 call %[bpf_map_lookup_elem]; \
815 if r0 == 0 goto l0_%=; \
816 r1 = 49; \
817 r0 += r1; \
818 r1 = *(u8*)(r0 + 0); \
819l0_%=: r0 = 1; \
820 exit; \
821" :
822 : __imm(bpf_map_lookup_elem),
823 __imm_addr(map_array_48b)
824 : __clobber_all);
825}
826
827SEC("socket")
828__description("map access: value_ptr += known scalar, 3")
829__failure __msg("invalid access to map value")
830__failure_unpriv
831__naked void value_ptr_known_scalar_3(void)
832{
833 asm volatile (" \
834 r1 = 0; \
835 *(u64*)(r10 - 8) = r1; \
836 r2 = r10; \
837 r2 += -8; \
838 r1 = %[map_array_48b] ll; \
839 call %[bpf_map_lookup_elem]; \
840 if r0 == 0 goto l0_%=; \
841 r1 = -1; \
842 r0 += r1; \
843 r1 = *(u8*)(r0 + 0); \
844l0_%=: r0 = 1; \
845 exit; \
846" :
847 : __imm(bpf_map_lookup_elem),
848 __imm_addr(map_array_48b)
849 : __clobber_all);
850}
851
852SEC("socket")
853__description("map access: value_ptr += known scalar, 4")
854__success __success_unpriv __retval(1)
855__naked void value_ptr_known_scalar_4(void)
856{
857 asm volatile (" \
858 r1 = 0; \
859 *(u64*)(r10 - 8) = r1; \
860 r2 = r10; \
861 r2 += -8; \
862 r1 = %[map_array_48b] ll; \
863 call %[bpf_map_lookup_elem]; \
864 if r0 == 0 goto l0_%=; \
865 r1 = 5; \
866 r0 += r1; \
867 r1 = -2; \
868 r0 += r1; \
869 r1 = -1; \
870 r0 += r1; \
871 r1 = *(u8*)(r0 + 0); \
872l0_%=: r0 = 1; \
873 exit; \
874" :
875 : __imm(bpf_map_lookup_elem),
876 __imm_addr(map_array_48b)
877 : __clobber_all);
878}
879
880SEC("socket")
881__description("map access: value_ptr += known scalar, 5")
882__success __success_unpriv __retval(0xabcdef12)
883__naked void value_ptr_known_scalar_5(void)
884{
885 asm volatile (" \
886 r1 = 0; \
887 *(u64*)(r10 - 8) = r1; \
888 r2 = r10; \
889 r2 += -8; \
890 r1 = %[map_array_48b] ll; \
891 call %[bpf_map_lookup_elem]; \
892 if r0 == 0 goto l0_%=; \
893 r1 = %[__imm_0]; \
894 r1 += r0; \
895 r0 = *(u32*)(r1 + 0); \
896l0_%=: exit; \
897" :
898 : __imm(bpf_map_lookup_elem),
899 __imm_addr(map_array_48b),
900 __imm_const(__imm_0, (6 + 1) * sizeof(int))
901 : __clobber_all);
902}
903
904SEC("socket")
905__description("map access: value_ptr += known scalar, 6")
906__success __success_unpriv __retval(0xabcdef12)
907__naked void value_ptr_known_scalar_6(void)
908{
909 asm volatile (" \
910 r1 = 0; \
911 *(u64*)(r10 - 8) = r1; \
912 r2 = r10; \
913 r2 += -8; \
914 r1 = %[map_array_48b] ll; \
915 call %[bpf_map_lookup_elem]; \
916 if r0 == 0 goto l0_%=; \
917 r1 = %[__imm_0]; \
918 r0 += r1; \
919 r1 = %[__imm_1]; \
920 r0 += r1; \
921 r0 = *(u32*)(r0 + 0); \
922l0_%=: exit; \
923" :
924 : __imm(bpf_map_lookup_elem),
925 __imm_addr(map_array_48b),
926 __imm_const(__imm_0, (3 + 1) * sizeof(int)),
927 __imm_const(__imm_1, 3 * sizeof(int))
928 : __clobber_all);
929}
930
931SEC("socket")
932__description("map access: value_ptr += N, value_ptr -= N known scalar")
933__success __success_unpriv __retval(0x12345678)
934__naked void value_ptr_n_known_scalar(void)
935{
936 asm volatile (" \
937 r1 = 0; \
938 *(u64*)(r10 - 8) = r1; \
939 r2 = r10; \
940 r2 += -8; \
941 r1 = %[map_array_48b] ll; \
942 call %[bpf_map_lookup_elem]; \
943 if r0 == 0 goto l0_%=; \
944 w1 = 0x12345678; \
945 *(u32*)(r0 + 0) = r1; \
946 r0 += 2; \
947 r1 = 2; \
948 r0 -= r1; \
949 r0 = *(u32*)(r0 + 0); \
950l0_%=: exit; \
951" :
952 : __imm(bpf_map_lookup_elem),
953 __imm_addr(map_array_48b)
954 : __clobber_all);
955}
956
957SEC("socket")
958__description("map access: unknown scalar += value_ptr, 1")
959__success __success_unpriv __retval(1)
960__naked void unknown_scalar_value_ptr_1(void)
961{
962 asm volatile (" \
963 r1 = 0; \
964 *(u64*)(r10 - 8) = r1; \
965 r2 = r10; \
966 r2 += -8; \
967 r1 = %[map_array_48b] ll; \
968 call %[bpf_map_lookup_elem]; \
969 if r0 == 0 goto l0_%=; \
970 r1 = *(u8*)(r0 + 0); \
971 r1 &= 0xf; \
972 r1 += r0; \
973 r0 = *(u8*)(r1 + 0); \
974l0_%=: r0 = 1; \
975 exit; \
976" :
977 : __imm(bpf_map_lookup_elem),
978 __imm_addr(map_array_48b)
979 : __clobber_all);
980}
981
982SEC("socket")
983__description("map access: unknown scalar += value_ptr, 2")
984__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
985__naked void unknown_scalar_value_ptr_2(void)
986{
987 asm volatile (" \
988 r1 = 0; \
989 *(u64*)(r10 - 8) = r1; \
990 r2 = r10; \
991 r2 += -8; \
992 r1 = %[map_array_48b] ll; \
993 call %[bpf_map_lookup_elem]; \
994 if r0 == 0 goto l0_%=; \
995 r1 = *(u32*)(r0 + 0); \
996 r1 &= 31; \
997 r1 += r0; \
998 r0 = *(u32*)(r1 + 0); \
999l0_%=: exit; \
1000" :
1001 : __imm(bpf_map_lookup_elem),
1002 __imm_addr(map_array_48b)
1003 : __clobber_all);
1004}
1005
1006SEC("socket")
1007__description("map access: unknown scalar += value_ptr, 3")
1008__success __failure_unpriv
1009__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
1010__retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
1011__naked void unknown_scalar_value_ptr_3(void)
1012{
1013 asm volatile (" \
1014 r1 = 0; \
1015 *(u64*)(r10 - 8) = r1; \
1016 r2 = r10; \
1017 r2 += -8; \
1018 r1 = %[map_array_48b] ll; \
1019 call %[bpf_map_lookup_elem]; \
1020 if r0 == 0 goto l0_%=; \
1021 r1 = -1; \
1022 r0 += r1; \
1023 r1 = 1; \
1024 r0 += r1; \
1025 r1 = *(u32*)(r0 + 0); \
1026 r1 &= 31; \
1027 r1 += r0; \
1028 r0 = *(u32*)(r1 + 0); \
1029l0_%=: exit; \
1030" :
1031 : __imm(bpf_map_lookup_elem),
1032 __imm_addr(map_array_48b)
1033 : __clobber_all);
1034}
1035
1036SEC("socket")
1037__description("map access: unknown scalar += value_ptr, 4")
1038__failure __msg("R1 max value is outside of the allowed memory range")
1039__msg_unpriv("R1 pointer arithmetic of map value goes out of range")
1040__flag(BPF_F_ANY_ALIGNMENT)
1041__naked void unknown_scalar_value_ptr_4(void)
1042{
1043 asm volatile (" \
1044 r1 = 0; \
1045 *(u64*)(r10 - 8) = r1; \
1046 r2 = r10; \
1047 r2 += -8; \
1048 r1 = %[map_array_48b] ll; \
1049 call %[bpf_map_lookup_elem]; \
1050 if r0 == 0 goto l0_%=; \
1051 r1 = 19; \
1052 r0 += r1; \
1053 r1 = *(u32*)(r0 + 0); \
1054 r1 &= 31; \
1055 r1 += r0; \
1056 r0 = *(u32*)(r1 + 0); \
1057l0_%=: exit; \
1058" :
1059 : __imm(bpf_map_lookup_elem),
1060 __imm_addr(map_array_48b)
1061 : __clobber_all);
1062}
1063
1064SEC("socket")
1065__description("map access: value_ptr += unknown scalar, 1")
1066__success __success_unpriv __retval(1)
1067__naked void value_ptr_unknown_scalar_1(void)
1068{
1069 asm volatile (" \
1070 r1 = 0; \
1071 *(u64*)(r10 - 8) = r1; \
1072 r2 = r10; \
1073 r2 += -8; \
1074 r1 = %[map_array_48b] ll; \
1075 call %[bpf_map_lookup_elem]; \
1076 if r0 == 0 goto l0_%=; \
1077 r1 = *(u8*)(r0 + 0); \
1078 r1 &= 0xf; \
1079 r0 += r1; \
1080 r1 = *(u8*)(r0 + 0); \
1081l0_%=: r0 = 1; \
1082 exit; \
1083" :
1084 : __imm(bpf_map_lookup_elem),
1085 __imm_addr(map_array_48b)
1086 : __clobber_all);
1087}
1088
1089SEC("socket")
1090__description("map access: value_ptr += unknown scalar, 2")
1091__success __success_unpriv __retval(0xabcdef12) __flag(BPF_F_ANY_ALIGNMENT)
1092__naked void value_ptr_unknown_scalar_2_1(void)
1093{
1094 asm volatile (" \
1095 r1 = 0; \
1096 *(u64*)(r10 - 8) = r1; \
1097 r2 = r10; \
1098 r2 += -8; \
1099 r1 = %[map_array_48b] ll; \
1100 call %[bpf_map_lookup_elem]; \
1101 if r0 == 0 goto l0_%=; \
1102 r1 = *(u32*)(r0 + 0); \
1103 r1 &= 31; \
1104 r0 += r1; \
1105 r0 = *(u32*)(r0 + 0); \
1106l0_%=: exit; \
1107" :
1108 : __imm(bpf_map_lookup_elem),
1109 __imm_addr(map_array_48b)
1110 : __clobber_all);
1111}
1112
1113SEC("socket")
1114__description("map access: value_ptr += unknown scalar, 3")
1115__success __success_unpriv __retval(1)
1116__naked void value_ptr_unknown_scalar_3(void)
1117{
1118 asm volatile (" \
1119 r1 = 0; \
1120 *(u64*)(r10 - 8) = r1; \
1121 r2 = r10; \
1122 r2 += -8; \
1123 r1 = %[map_array_48b] ll; \
1124 call %[bpf_map_lookup_elem]; \
1125 if r0 == 0 goto l0_%=; \
1126 r1 = *(u64*)(r0 + 0); \
1127 r2 = *(u64*)(r0 + 8); \
1128 r3 = *(u64*)(r0 + 16); \
1129 r1 &= 0xf; \
1130 r3 &= 1; \
1131 r3 |= 1; \
1132 if r2 > r3 goto l0_%=; \
1133 r0 += r3; \
1134 r0 = *(u8*)(r0 + 0); \
1135 r0 = 1; \
1136l1_%=: exit; \
1137l0_%=: r0 = 2; \
1138 goto l1_%=; \
1139" :
1140 : __imm(bpf_map_lookup_elem),
1141 __imm_addr(map_array_48b)
1142 : __clobber_all);
1143}
1144
1145SEC("socket")
1146__description("map access: value_ptr += value_ptr")
1147__failure __msg("R0 pointer += pointer prohibited")
1148__failure_unpriv
1149__naked void access_value_ptr_value_ptr_1(void)
1150{
1151 asm volatile (" \
1152 r1 = 0; \
1153 *(u64*)(r10 - 8) = r1; \
1154 r2 = r10; \
1155 r2 += -8; \
1156 r1 = %[map_array_48b] ll; \
1157 call %[bpf_map_lookup_elem]; \
1158 if r0 == 0 goto l0_%=; \
1159 r0 += r0; \
1160 r1 = *(u8*)(r0 + 0); \
1161l0_%=: r0 = 1; \
1162 exit; \
1163" :
1164 : __imm(bpf_map_lookup_elem),
1165 __imm_addr(map_array_48b)
1166 : __clobber_all);
1167}
1168
1169SEC("socket")
1170__description("map access: known scalar -= value_ptr")
1171__failure __msg("R1 tried to subtract pointer from scalar")
1172__failure_unpriv
1173__naked void access_known_scalar_value_ptr_2(void)
1174{
1175 asm volatile (" \
1176 r1 = 0; \
1177 *(u64*)(r10 - 8) = r1; \
1178 r2 = r10; \
1179 r2 += -8; \
1180 r1 = %[map_array_48b] ll; \
1181 call %[bpf_map_lookup_elem]; \
1182 if r0 == 0 goto l0_%=; \
1183 r1 = 4; \
1184 r1 -= r0; \
1185 r0 = *(u8*)(r1 + 0); \
1186l0_%=: r0 = 1; \
1187 exit; \
1188" :
1189 : __imm(bpf_map_lookup_elem),
1190 __imm_addr(map_array_48b)
1191 : __clobber_all);
1192}
1193
1194SEC("socket")
1195__description("map access: value_ptr -= known scalar")
1196__failure __msg("R0 min value is outside of the allowed memory range")
1197__failure_unpriv
1198__naked void access_value_ptr_known_scalar(void)
1199{
1200 asm volatile (" \
1201 r1 = 0; \
1202 *(u64*)(r10 - 8) = r1; \
1203 r2 = r10; \
1204 r2 += -8; \
1205 r1 = %[map_array_48b] ll; \
1206 call %[bpf_map_lookup_elem]; \
1207 if r0 == 0 goto l0_%=; \
1208 r1 = 4; \
1209 r0 -= r1; \
1210 r1 = *(u8*)(r0 + 0); \
1211l0_%=: r0 = 1; \
1212 exit; \
1213" :
1214 : __imm(bpf_map_lookup_elem),
1215 __imm_addr(map_array_48b)
1216 : __clobber_all);
1217}
1218
1219SEC("socket")
1220__description("map access: value_ptr -= known scalar, 2")
1221__success __success_unpriv __retval(1)
1222__naked void value_ptr_known_scalar_2_2(void)
1223{
1224 asm volatile (" \
1225 r1 = 0; \
1226 *(u64*)(r10 - 8) = r1; \
1227 r2 = r10; \
1228 r2 += -8; \
1229 r1 = %[map_array_48b] ll; \
1230 call %[bpf_map_lookup_elem]; \
1231 if r0 == 0 goto l0_%=; \
1232 r1 = 6; \
1233 r2 = 4; \
1234 r0 += r1; \
1235 r0 -= r2; \
1236 r1 = *(u8*)(r0 + 0); \
1237l0_%=: r0 = 1; \
1238 exit; \
1239" :
1240 : __imm(bpf_map_lookup_elem),
1241 __imm_addr(map_array_48b)
1242 : __clobber_all);
1243}
1244
1245SEC("socket")
1246__description("map access: unknown scalar -= value_ptr")
1247__failure __msg("R1 tried to subtract pointer from scalar")
1248__failure_unpriv
1249__naked void access_unknown_scalar_value_ptr(void)
1250{
1251 asm volatile (" \
1252 r1 = 0; \
1253 *(u64*)(r10 - 8) = r1; \
1254 r2 = r10; \
1255 r2 += -8; \
1256 r1 = %[map_array_48b] ll; \
1257 call %[bpf_map_lookup_elem]; \
1258 if r0 == 0 goto l0_%=; \
1259 r1 = *(u8*)(r0 + 0); \
1260 r1 &= 0xf; \
1261 r1 -= r0; \
1262 r0 = *(u8*)(r1 + 0); \
1263l0_%=: r0 = 1; \
1264 exit; \
1265" :
1266 : __imm(bpf_map_lookup_elem),
1267 __imm_addr(map_array_48b)
1268 : __clobber_all);
1269}
1270
1271SEC("socket")
1272__description("map access: value_ptr -= unknown scalar")
1273__failure __msg("R0 min value is negative")
1274__failure_unpriv
1275__naked void access_value_ptr_unknown_scalar(void)
1276{
1277 asm volatile (" \
1278 r1 = 0; \
1279 *(u64*)(r10 - 8) = r1; \
1280 r2 = r10; \
1281 r2 += -8; \
1282 r1 = %[map_array_48b] ll; \
1283 call %[bpf_map_lookup_elem]; \
1284 if r0 == 0 goto l0_%=; \
1285 r1 = *(u8*)(r0 + 0); \
1286 r1 &= 0xf; \
1287 r0 -= r1; \
1288 r1 = *(u8*)(r0 + 0); \
1289l0_%=: r0 = 1; \
1290 exit; \
1291" :
1292 : __imm(bpf_map_lookup_elem),
1293 __imm_addr(map_array_48b)
1294 : __clobber_all);
1295}
1296
1297SEC("socket")
1298__description("map access: value_ptr -= unknown scalar, 2")
1299__success __failure_unpriv
1300__msg_unpriv("R0 pointer arithmetic of map value goes out of range")
1301__retval(1)
1302__naked void value_ptr_unknown_scalar_2_2(void)
1303{
1304 asm volatile (" \
1305 r1 = 0; \
1306 *(u64*)(r10 - 8) = r1; \
1307 r2 = r10; \
1308 r2 += -8; \
1309 r1 = %[map_array_48b] ll; \
1310 call %[bpf_map_lookup_elem]; \
1311 if r0 == 0 goto l0_%=; \
1312 r1 = *(u8*)(r0 + 0); \
1313 r1 &= 0xf; \
1314 r1 |= 0x7; \
1315 r0 += r1; \
1316 r1 = *(u8*)(r0 + 0); \
1317 r1 &= 0x7; \
1318 r0 -= r1; \
1319 r1 = *(u8*)(r0 + 0); \
1320l0_%=: r0 = 1; \
1321 exit; \
1322" :
1323 : __imm(bpf_map_lookup_elem),
1324 __imm_addr(map_array_48b)
1325 : __clobber_all);
1326}
1327
1328SEC("socket")
1329__description("map access: value_ptr -= value_ptr")
1330__failure __msg("R0 invalid mem access 'scalar'")
1331__msg_unpriv("R0 pointer -= pointer prohibited")
1332__naked void access_value_ptr_value_ptr_2(void)
1333{
1334 asm volatile (" \
1335 r1 = 0; \
1336 *(u64*)(r10 - 8) = r1; \
1337 r2 = r10; \
1338 r2 += -8; \
1339 r1 = %[map_array_48b] ll; \
1340 call %[bpf_map_lookup_elem]; \
1341 if r0 == 0 goto l0_%=; \
1342 r0 -= r0; \
1343 r1 = *(u8*)(r0 + 0); \
1344l0_%=: r0 = 1; \
1345 exit; \
1346" :
1347 : __imm(bpf_map_lookup_elem),
1348 __imm_addr(map_array_48b)
1349 : __clobber_all);
1350}
1351
1352SEC("socket")
1353__description("map access: trying to leak tainted dst reg")
1354__failure __msg("math between map_value pointer and 4294967295 is not allowed")
1355__failure_unpriv
1356__naked void to_leak_tainted_dst_reg(void)
1357{
1358 asm volatile (" \
1359 r0 = 0; \
1360 r1 = 0; \
1361 *(u64*)(r10 - 8) = r1; \
1362 r2 = r10; \
1363 r2 += -8; \
1364 r1 = %[map_array_48b] ll; \
1365 call %[bpf_map_lookup_elem]; \
1366 if r0 != 0 goto l0_%=; \
1367 exit; \
1368l0_%=: r2 = r0; \
1369 w1 = 0xFFFFFFFF; \
1370 w1 = w1; \
1371 r2 -= r1; \
1372 *(u64*)(r0 + 0) = r2; \
1373 r0 = 0; \
1374 exit; \
1375" :
1376 : __imm(bpf_map_lookup_elem),
1377 __imm_addr(map_array_48b)
1378 : __clobber_all);
1379}
1380
1381SEC("tc")
1382__description("32bit pkt_ptr -= scalar")
1383__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
1384__naked void _32bit_pkt_ptr_scalar(void)
1385{
1386 asm volatile (" \
1387 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \
1388 r7 = *(u32*)(r1 + %[__sk_buff_data]); \
1389 r6 = r7; \
1390 r6 += 40; \
1391 if r6 > r8 goto l0_%=; \
1392 w4 = w7; \
1393 w6 -= w4; \
1394l0_%=: r0 = 0; \
1395 exit; \
1396" :
1397 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
1398 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
1399 : __clobber_all);
1400}
1401
1402SEC("tc")
1403__description("32bit scalar -= pkt_ptr")
1404__success __retval(0) __flag(BPF_F_ANY_ALIGNMENT)
1405__naked void _32bit_scalar_pkt_ptr(void)
1406{
1407 asm volatile (" \
1408 r8 = *(u32*)(r1 + %[__sk_buff_data_end]); \
1409 r7 = *(u32*)(r1 + %[__sk_buff_data]); \
1410 r6 = r7; \
1411 r6 += 40; \
1412 if r6 > r8 goto l0_%=; \
1413 w4 = w6; \
1414 w4 -= w7; \
1415l0_%=: r0 = 0; \
1416 exit; \
1417" :
1418 : __imm_const(__sk_buff_data, offsetof(struct __sk_buff, data)),
1419 __imm_const(__sk_buff_data_end, offsetof(struct __sk_buff, data_end))
1420 : __clobber_all);
1421}
1422
1423char _license[] SEC("license") = "GPL";
1424

source code of linux/tools/testing/selftests/bpf/progs/verifier_value_ptr_arith.c