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