1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Facebook */
3
4 #include <errno.h>
5 #include <string.h>
6 #include <stdbool.h>
7 #include <linux/bpf.h>
8 #include <bpf/bpf_helpers.h>
9 #include <bpf/bpf_tracing.h>
10 #include <linux/if_ether.h>
11 #include "bpf_misc.h"
12 #include "bpf_kfuncs.h"
13
14 char _license[] SEC("license") = "GPL";
15
16 struct test_info {
17 int x;
18 struct bpf_dynptr ptr;
19 };
20
21 struct {
22 __uint(type, BPF_MAP_TYPE_ARRAY);
23 __uint(max_entries, 1);
24 __type(key, __u32);
25 __type(value, struct bpf_dynptr);
26 } array_map1 SEC(".maps");
27
28 struct {
29 __uint(type, BPF_MAP_TYPE_ARRAY);
30 __uint(max_entries, 1);
31 __type(key, __u32);
32 __type(value, struct test_info);
33 } array_map2 SEC(".maps");
34
35 struct {
36 __uint(type, BPF_MAP_TYPE_ARRAY);
37 __uint(max_entries, 1);
38 __type(key, __u32);
39 __type(value, __u32);
40 } array_map3 SEC(".maps");
41
42 struct {
43 __uint(type, BPF_MAP_TYPE_ARRAY);
44 __uint(max_entries, 1);
45 __type(key, __u32);
46 __type(value, __u64);
47 } array_map4 SEC(".maps");
48
49 struct sample {
50 int pid;
51 long value;
52 char comm[16];
53 };
54
55 struct {
56 __uint(type, BPF_MAP_TYPE_RINGBUF);
57 __uint(max_entries, 4096);
58 } ringbuf SEC(".maps");
59
60 int err, val;
61
get_map_val_dynptr(struct bpf_dynptr * ptr)62 static int get_map_val_dynptr(struct bpf_dynptr *ptr)
63 {
64 __u32 key = 0, *map_val;
65
66 bpf_map_update_elem(&array_map3, &key, &val, 0);
67
68 map_val = bpf_map_lookup_elem(&array_map3, &key);
69 if (!map_val)
70 return -ENOENT;
71
72 bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr);
73
74 return 0;
75 }
76
77 /* Every bpf_ringbuf_reserve_dynptr call must have a corresponding
78 * bpf_ringbuf_submit/discard_dynptr call
79 */
80 SEC("?raw_tp")
81 __failure __msg("Unreleased reference id=1")
ringbuf_missing_release1(void * ctx)82 int ringbuf_missing_release1(void *ctx)
83 {
84 struct bpf_dynptr ptr = {};
85
86 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
87
88 /* missing a call to bpf_ringbuf_discard/submit_dynptr */
89
90 return 0;
91 }
92
93 SEC("?raw_tp")
94 __failure __msg("Unreleased reference id=3")
ringbuf_missing_release2(void * ctx)95 int ringbuf_missing_release2(void *ctx)
96 {
97 struct bpf_dynptr ptr1, ptr2;
98 struct sample *sample;
99
100 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1);
101 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
102
103 sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample));
104 if (!sample) {
105 bpf_ringbuf_discard_dynptr(&ptr1, 0);
106 bpf_ringbuf_discard_dynptr(&ptr2, 0);
107 return 0;
108 }
109
110 bpf_ringbuf_submit_dynptr(&ptr1, 0);
111
112 /* missing a call to bpf_ringbuf_discard/submit_dynptr on ptr2 */
113
114 return 0;
115 }
116
missing_release_callback_fn(__u32 index,void * data)117 static int missing_release_callback_fn(__u32 index, void *data)
118 {
119 struct bpf_dynptr ptr;
120
121 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
122
123 /* missing a call to bpf_ringbuf_discard/submit_dynptr */
124
125 return 0;
126 }
127
128 /* Any dynptr initialized within a callback must have bpf_dynptr_put called */
129 SEC("?raw_tp")
130 __failure __msg("Unreleased reference id")
ringbuf_missing_release_callback(void * ctx)131 int ringbuf_missing_release_callback(void *ctx)
132 {
133 bpf_loop(10, missing_release_callback_fn, NULL, 0);
134 return 0;
135 }
136
137 /* Can't call bpf_ringbuf_submit/discard_dynptr on a non-initialized dynptr */
138 SEC("?raw_tp")
139 __failure __msg("Expected an initialized dynptr as R1")
ringbuf_release_uninit_dynptr(void * ctx)140 int ringbuf_release_uninit_dynptr(void *ctx)
141 {
142 struct bpf_dynptr ptr;
143
144 /* this should fail */
145 bpf_ringbuf_submit_dynptr(&ptr, 0);
146
147 return 0;
148 }
149
150 /* A dynptr can't be used after it has been invalidated */
151 SEC("?raw_tp")
152 __failure __msg("Expected an initialized dynptr as R3")
use_after_invalid(void * ctx)153 int use_after_invalid(void *ctx)
154 {
155 struct bpf_dynptr ptr;
156 char read_data[64];
157
158 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr);
159
160 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
161
162 bpf_ringbuf_submit_dynptr(&ptr, 0);
163
164 /* this should fail */
165 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
166
167 return 0;
168 }
169
170 /* Can't call non-dynptr ringbuf APIs on a dynptr ringbuf sample */
171 SEC("?raw_tp")
172 __failure __msg("type=mem expected=ringbuf_mem")
ringbuf_invalid_api(void * ctx)173 int ringbuf_invalid_api(void *ctx)
174 {
175 struct bpf_dynptr ptr;
176 struct sample *sample;
177
178 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
179 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
180 if (!sample)
181 goto done;
182
183 sample->pid = 123;
184
185 /* invalid API use. need to use dynptr API to submit/discard */
186 bpf_ringbuf_submit(sample, 0);
187
188 done:
189 bpf_ringbuf_discard_dynptr(&ptr, 0);
190 return 0;
191 }
192
193 /* Can't add a dynptr to a map */
194 SEC("?raw_tp")
195 __failure __msg("invalid read from stack")
add_dynptr_to_map1(void * ctx)196 int add_dynptr_to_map1(void *ctx)
197 {
198 struct bpf_dynptr ptr;
199 int key = 0;
200
201 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
202
203 /* this should fail */
204 bpf_map_update_elem(&array_map1, &key, &ptr, 0);
205
206 bpf_ringbuf_submit_dynptr(&ptr, 0);
207
208 return 0;
209 }
210
211 /* Can't add a struct with an embedded dynptr to a map */
212 SEC("?raw_tp")
213 __failure __msg("invalid read from stack")
add_dynptr_to_map2(void * ctx)214 int add_dynptr_to_map2(void *ctx)
215 {
216 struct test_info x;
217 int key = 0;
218
219 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr);
220
221 /* this should fail */
222 bpf_map_update_elem(&array_map2, &key, &x, 0);
223
224 bpf_ringbuf_submit_dynptr(&x.ptr, 0);
225
226 return 0;
227 }
228
229 /* A data slice can't be accessed out of bounds */
230 SEC("?raw_tp")
231 __failure __msg("value is outside of the allowed memory range")
data_slice_out_of_bounds_ringbuf(void * ctx)232 int data_slice_out_of_bounds_ringbuf(void *ctx)
233 {
234 struct bpf_dynptr ptr;
235 void *data;
236
237 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
238
239 data = bpf_dynptr_data(&ptr, 0, 8);
240 if (!data)
241 goto done;
242
243 /* can't index out of bounds of the data slice */
244 val = *((char *)data + 8);
245
246 done:
247 bpf_ringbuf_submit_dynptr(&ptr, 0);
248 return 0;
249 }
250
251 /* A data slice can't be accessed out of bounds */
252 SEC("?tc")
253 __failure __msg("value is outside of the allowed memory range")
data_slice_out_of_bounds_skb(struct __sk_buff * skb)254 int data_slice_out_of_bounds_skb(struct __sk_buff *skb)
255 {
256 struct bpf_dynptr ptr;
257 struct ethhdr *hdr;
258 char buffer[sizeof(*hdr)] = {};
259
260 bpf_dynptr_from_skb(skb, 0, &ptr);
261
262 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
263 if (!hdr)
264 return SK_DROP;
265
266 /* this should fail */
267 *(__u8*)(hdr + 1) = 1;
268
269 return SK_PASS;
270 }
271
272 /* A metadata slice can't be accessed out of bounds */
273 SEC("?tc")
274 __failure __msg("value is outside of the allowed memory range")
data_slice_out_of_bounds_skb_meta(struct __sk_buff * skb)275 int data_slice_out_of_bounds_skb_meta(struct __sk_buff *skb)
276 {
277 struct bpf_dynptr meta;
278 __u8 *md;
279
280 bpf_dynptr_from_skb_meta(skb, 0, &meta);
281
282 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md));
283 if (!md)
284 return SK_DROP;
285
286 /* this should fail */
287 *(md + 1) = 42;
288
289 return SK_PASS;
290 }
291
292 SEC("?raw_tp")
293 __failure __msg("value is outside of the allowed memory range")
data_slice_out_of_bounds_map_value(void * ctx)294 int data_slice_out_of_bounds_map_value(void *ctx)
295 {
296 __u32 map_val;
297 struct bpf_dynptr ptr;
298 void *data;
299
300 get_map_val_dynptr(&ptr);
301
302 data = bpf_dynptr_data(&ptr, 0, sizeof(map_val));
303 if (!data)
304 return 0;
305
306 /* can't index out of bounds of the data slice */
307 val = *((char *)data + (sizeof(map_val) + 1));
308
309 return 0;
310 }
311
312 /* A data slice can't be used after it has been released */
313 SEC("?raw_tp")
314 __failure __msg("invalid mem access 'scalar'")
data_slice_use_after_release1(void * ctx)315 int data_slice_use_after_release1(void *ctx)
316 {
317 struct bpf_dynptr ptr;
318 struct sample *sample;
319
320 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
321 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
322 if (!sample)
323 goto done;
324
325 sample->pid = 123;
326
327 bpf_ringbuf_submit_dynptr(&ptr, 0);
328
329 /* this should fail */
330 val = sample->pid;
331
332 return 0;
333
334 done:
335 bpf_ringbuf_discard_dynptr(&ptr, 0);
336 return 0;
337 }
338
339 /* A data slice can't be used after it has been released.
340 *
341 * This tests the case where the data slice tracks a dynptr (ptr2)
342 * that is at a non-zero offset from the frame pointer (ptr1 is at fp,
343 * ptr2 is at fp - 16).
344 */
345 SEC("?raw_tp")
346 __failure __msg("invalid mem access 'scalar'")
data_slice_use_after_release2(void * ctx)347 int data_slice_use_after_release2(void *ctx)
348 {
349 struct bpf_dynptr ptr1, ptr2;
350 struct sample *sample;
351
352 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr1);
353 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
354
355 sample = bpf_dynptr_data(&ptr2, 0, sizeof(*sample));
356 if (!sample)
357 goto done;
358
359 sample->pid = 23;
360
361 bpf_ringbuf_submit_dynptr(&ptr2, 0);
362
363 /* this should fail */
364 sample->pid = 23;
365
366 bpf_ringbuf_submit_dynptr(&ptr1, 0);
367
368 return 0;
369
370 done:
371 bpf_ringbuf_discard_dynptr(&ptr2, 0);
372 bpf_ringbuf_discard_dynptr(&ptr1, 0);
373 return 0;
374 }
375
376 /* A data slice must be first checked for NULL */
377 SEC("?raw_tp")
378 __failure __msg("invalid mem access 'mem_or_null'")
data_slice_missing_null_check1(void * ctx)379 int data_slice_missing_null_check1(void *ctx)
380 {
381 struct bpf_dynptr ptr;
382 void *data;
383
384 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
385
386 data = bpf_dynptr_data(&ptr, 0, 8);
387
388 /* missing if (!data) check */
389
390 /* this should fail */
391 *(__u8 *)data = 3;
392
393 bpf_ringbuf_submit_dynptr(&ptr, 0);
394 return 0;
395 }
396
397 /* A data slice can't be dereferenced if it wasn't checked for null */
398 SEC("?raw_tp")
399 __failure __msg("invalid mem access 'mem_or_null'")
data_slice_missing_null_check2(void * ctx)400 int data_slice_missing_null_check2(void *ctx)
401 {
402 struct bpf_dynptr ptr;
403 __u64 *data1, *data2;
404
405 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
406
407 data1 = bpf_dynptr_data(&ptr, 0, 8);
408 data2 = bpf_dynptr_data(&ptr, 0, 8);
409 if (data1)
410 /* this should fail */
411 *data2 = 3;
412
413 bpf_ringbuf_discard_dynptr(&ptr, 0);
414 return 0;
415 }
416
417 /* Can't pass in a dynptr as an arg to a helper function that doesn't take in a
418 * dynptr argument
419 */
420 SEC("?raw_tp")
421 __failure __msg("invalid read from stack")
invalid_helper1(void * ctx)422 int invalid_helper1(void *ctx)
423 {
424 struct bpf_dynptr ptr;
425
426 get_map_val_dynptr(&ptr);
427
428 /* this should fail */
429 bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!");
430
431 return 0;
432 }
433
434 /* A dynptr can't be passed into a helper function at a non-zero offset */
435 SEC("?raw_tp")
436 __failure __msg("cannot pass in dynptr at an offset=-8")
invalid_helper2(void * ctx)437 int invalid_helper2(void *ctx)
438 {
439 struct bpf_dynptr ptr;
440 char read_data[64];
441
442 get_map_val_dynptr(&ptr);
443
444 /* this should fail */
445 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0);
446 return 0;
447 }
448
449 /* A bpf_dynptr is invalidated if it's been written into */
450 SEC("?raw_tp")
451 __failure __msg("Expected an initialized dynptr as R1")
invalid_write1(void * ctx)452 int invalid_write1(void *ctx)
453 {
454 struct bpf_dynptr ptr;
455 void *data;
456 __u8 x = 0;
457
458 get_map_val_dynptr(&ptr);
459
460 memcpy(&ptr, &x, sizeof(x));
461
462 /* this should fail */
463 data = bpf_dynptr_data(&ptr, 0, 1);
464 __sink(data);
465
466 return 0;
467 }
468
469 /*
470 * A bpf_dynptr can't be used as a dynptr if it has been written into at a fixed
471 * offset
472 */
473 SEC("?raw_tp")
474 __failure __msg("cannot overwrite referenced dynptr")
invalid_write2(void * ctx)475 int invalid_write2(void *ctx)
476 {
477 struct bpf_dynptr ptr;
478 char read_data[64];
479 __u8 x = 0;
480
481 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
482
483 memcpy((void *)&ptr + 8, &x, sizeof(x));
484
485 /* this should fail */
486 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
487
488 bpf_ringbuf_submit_dynptr(&ptr, 0);
489
490 return 0;
491 }
492
493 /*
494 * A bpf_dynptr can't be used as a dynptr if it has been written into at a
495 * non-const offset
496 */
497 SEC("?raw_tp")
498 __failure __msg("cannot overwrite referenced dynptr")
invalid_write3(void * ctx)499 int invalid_write3(void *ctx)
500 {
501 struct bpf_dynptr ptr;
502 char stack_buf[16];
503 unsigned long len;
504 __u8 x = 0;
505
506 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
507
508 memcpy(stack_buf, &val, sizeof(val));
509 len = stack_buf[0] & 0xf;
510
511 memcpy((void *)&ptr + len, &x, sizeof(x));
512
513 /* this should fail */
514 bpf_ringbuf_submit_dynptr(&ptr, 0);
515
516 return 0;
517 }
518
invalid_write4_callback(__u32 index,void * data)519 static int invalid_write4_callback(__u32 index, void *data)
520 {
521 *(__u32 *)data = 123;
522
523 return 0;
524 }
525
526 /* If the dynptr is written into in a callback function, it should
527 * be invalidated as a dynptr
528 */
529 SEC("?raw_tp")
530 __failure __msg("cannot overwrite referenced dynptr")
invalid_write4(void * ctx)531 int invalid_write4(void *ctx)
532 {
533 struct bpf_dynptr ptr;
534
535 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
536
537 bpf_loop(10, invalid_write4_callback, &ptr, 0);
538
539 /* this should fail */
540 bpf_ringbuf_submit_dynptr(&ptr, 0);
541
542 return 0;
543 }
544
545 /* A globally-defined bpf_dynptr can't be used (it must reside as a stack frame) */
546 struct bpf_dynptr global_dynptr;
547
548 SEC("?raw_tp")
549 __failure __msg("type=map_value expected=fp")
global(void * ctx)550 int global(void *ctx)
551 {
552 /* this should fail */
553 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr);
554
555 bpf_ringbuf_discard_dynptr(&global_dynptr, 0);
556
557 return 0;
558 }
559
560 /* A direct read should fail */
561 SEC("?raw_tp")
562 __failure __msg("invalid read from stack")
invalid_read1(void * ctx)563 int invalid_read1(void *ctx)
564 {
565 struct bpf_dynptr ptr;
566
567 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
568
569 /* this should fail */
570 val = *(int *)&ptr;
571
572 bpf_ringbuf_discard_dynptr(&ptr, 0);
573
574 return 0;
575 }
576
577 /* A direct read at an offset should fail */
578 SEC("?raw_tp")
579 __failure __msg("cannot pass in dynptr at an offset")
invalid_read2(void * ctx)580 int invalid_read2(void *ctx)
581 {
582 struct bpf_dynptr ptr;
583 char read_data[64];
584
585 get_map_val_dynptr(&ptr);
586
587 /* this should fail */
588 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0);
589
590 return 0;
591 }
592
593 /* A direct read at an offset into the lower stack slot should fail */
594 SEC("?raw_tp")
595 __failure __msg("invalid read from stack")
invalid_read3(void * ctx)596 int invalid_read3(void *ctx)
597 {
598 struct bpf_dynptr ptr1, ptr2;
599
600 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1);
601 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2);
602
603 /* this should fail */
604 memcpy(&val, (void *)&ptr1 + 8, sizeof(val));
605
606 bpf_ringbuf_discard_dynptr(&ptr1, 0);
607 bpf_ringbuf_discard_dynptr(&ptr2, 0);
608
609 return 0;
610 }
611
invalid_read4_callback(__u32 index,void * data)612 static int invalid_read4_callback(__u32 index, void *data)
613 {
614 /* this should fail */
615 val = *(__u32 *)data;
616
617 return 0;
618 }
619
620 /* A direct read within a callback function should fail */
621 SEC("?raw_tp")
622 __failure __msg("invalid read from stack")
invalid_read4(void * ctx)623 int invalid_read4(void *ctx)
624 {
625 struct bpf_dynptr ptr;
626
627 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
628
629 bpf_loop(10, invalid_read4_callback, &ptr, 0);
630
631 bpf_ringbuf_submit_dynptr(&ptr, 0);
632
633 return 0;
634 }
635
636 /* Initializing a dynptr on an offset should fail */
637 SEC("?raw_tp")
638 __failure __msg("cannot pass in dynptr at an offset=0")
invalid_offset(void * ctx)639 int invalid_offset(void *ctx)
640 {
641 struct bpf_dynptr ptr;
642
643 /* this should fail */
644 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1);
645
646 bpf_ringbuf_discard_dynptr(&ptr, 0);
647
648 return 0;
649 }
650
651 /* Can't release a dynptr twice */
652 SEC("?raw_tp")
653 __failure __msg("Expected an initialized dynptr as R1")
release_twice(void * ctx)654 int release_twice(void *ctx)
655 {
656 struct bpf_dynptr ptr;
657
658 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
659
660 bpf_ringbuf_discard_dynptr(&ptr, 0);
661
662 /* this second release should fail */
663 bpf_ringbuf_discard_dynptr(&ptr, 0);
664
665 return 0;
666 }
667
release_twice_callback_fn(__u32 index,void * data)668 static int release_twice_callback_fn(__u32 index, void *data)
669 {
670 /* this should fail */
671 bpf_ringbuf_discard_dynptr(data, 0);
672
673 return 0;
674 }
675
676 /* Test that releasing a dynptr twice, where one of the releases happens
677 * within a callback function, fails
678 */
679 SEC("?raw_tp")
680 __failure __msg("Expected an initialized dynptr as R1")
release_twice_callback(void * ctx)681 int release_twice_callback(void *ctx)
682 {
683 struct bpf_dynptr ptr;
684
685 bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr);
686
687 bpf_ringbuf_discard_dynptr(&ptr, 0);
688
689 bpf_loop(10, release_twice_callback_fn, &ptr, 0);
690
691 return 0;
692 }
693
694 /* Reject unsupported local mem types for dynptr_from_mem API */
695 SEC("?raw_tp")
696 __failure __msg("Unsupported reg type fp for bpf_dynptr_from_mem data")
dynptr_from_mem_invalid_api(void * ctx)697 int dynptr_from_mem_invalid_api(void *ctx)
698 {
699 struct bpf_dynptr ptr;
700 int x = 0;
701
702 /* this should fail */
703 bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr);
704
705 return 0;
706 }
707
708 /* Cannot create dynptr from dynptr data */
709 SEC("?raw_tp")
710 __failure __msg("Unsupported reg type mem for bpf_dynptr_from_mem data")
dynptr_from_dynptr_data(void * ctx)711 int dynptr_from_dynptr_data(void *ctx)
712 {
713 struct bpf_dynptr ptr, ptr2;
714 __u8 *data;
715
716 if (get_map_val_dynptr(&ptr))
717 return 0;
718
719 data = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
720 if (!data)
721 return 0;
722
723 /* this should fail */
724 bpf_dynptr_from_mem(data, sizeof(__u32), 0, &ptr2);
725
726 return 0;
727 }
728
729 /* Cannot create dynptr from dynptr slice */
730 SEC("?tc")
731 __failure __msg("Unsupported reg type mem for bpf_dynptr_from_mem data")
dynptr_from_dynptr_slice(struct __sk_buff * skb)732 int dynptr_from_dynptr_slice(struct __sk_buff *skb)
733 {
734 struct bpf_dynptr ptr, ptr2;
735 struct ethhdr *hdr;
736 char buffer[sizeof(*hdr)] = {};
737
738 bpf_dynptr_from_skb(skb, 0, &ptr);
739
740 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
741 if (!hdr)
742 return SK_DROP;
743
744 /* this should fail */
745 bpf_dynptr_from_mem(hdr, sizeof(*hdr), 0, &ptr2);
746
747 return SK_PASS;
748 }
749
750 SEC("?tc")
751 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
dynptr_pruning_overwrite(struct __sk_buff * ctx)752 int dynptr_pruning_overwrite(struct __sk_buff *ctx)
753 {
754 asm volatile (
755 "r9 = 0xeB9F; \
756 r6 = %[ringbuf] ll; \
757 r1 = r6; \
758 r2 = 8; \
759 r3 = 0; \
760 r4 = r10; \
761 r4 += -16; \
762 call %[bpf_ringbuf_reserve_dynptr]; \
763 if r0 == 0 goto pjmp1; \
764 goto pjmp2; \
765 pjmp1: \
766 *(u64 *)(r10 - 16) = r9; \
767 pjmp2: \
768 r1 = r10; \
769 r1 += -16; \
770 r2 = 0; \
771 call %[bpf_ringbuf_discard_dynptr]; "
772 :
773 : __imm(bpf_ringbuf_reserve_dynptr),
774 __imm(bpf_ringbuf_discard_dynptr),
775 __imm_addr(ringbuf)
776 : __clobber_all
777 );
778 return 0;
779 }
780
781 SEC("?tc")
782 __success __msg("12: safe") __log_level(2)
dynptr_pruning_stacksafe(struct __sk_buff * ctx)783 int dynptr_pruning_stacksafe(struct __sk_buff *ctx)
784 {
785 asm volatile (
786 "r9 = 0xeB9F; \
787 r6 = %[ringbuf] ll; \
788 r1 = r6; \
789 r2 = 8; \
790 r3 = 0; \
791 r4 = r10; \
792 r4 += -16; \
793 call %[bpf_ringbuf_reserve_dynptr]; \
794 if r0 == 0 goto stjmp1; \
795 goto stjmp2; \
796 stjmp1: \
797 r9 = r9; \
798 stjmp2: \
799 r1 = r10; \
800 r1 += -16; \
801 r2 = 0; \
802 call %[bpf_ringbuf_discard_dynptr]; "
803 :
804 : __imm(bpf_ringbuf_reserve_dynptr),
805 __imm(bpf_ringbuf_discard_dynptr),
806 __imm_addr(ringbuf)
807 : __clobber_all
808 );
809 return 0;
810 }
811
812 SEC("?tc")
813 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
dynptr_pruning_type_confusion(struct __sk_buff * ctx)814 int dynptr_pruning_type_confusion(struct __sk_buff *ctx)
815 {
816 asm volatile (
817 "r6 = %[array_map4] ll; \
818 r7 = %[ringbuf] ll; \
819 r1 = r6; \
820 r2 = r10; \
821 r2 += -8; \
822 r9 = 0; \
823 *(u64 *)(r2 + 0) = r9; \
824 r3 = r10; \
825 r3 += -24; \
826 r9 = 0xeB9FeB9F; \
827 *(u64 *)(r10 - 16) = r9; \
828 *(u64 *)(r10 - 24) = r9; \
829 r9 = 0; \
830 r4 = 0; \
831 r8 = r2; \
832 call %[bpf_map_update_elem]; \
833 r1 = r6; \
834 r2 = r8; \
835 call %[bpf_map_lookup_elem]; \
836 if r0 != 0 goto tjmp1; \
837 exit; \
838 tjmp1: \
839 r8 = r0; \
840 r1 = r7; \
841 r2 = 8; \
842 r3 = 0; \
843 r4 = r10; \
844 r4 += -16; \
845 r0 = *(u64 *)(r0 + 0); \
846 call %[bpf_ringbuf_reserve_dynptr]; \
847 if r0 == 0 goto tjmp2; \
848 r8 = r8; \
849 r8 = r8; \
850 r8 = r8; \
851 r8 = r8; \
852 r8 = r8; \
853 r8 = r8; \
854 r8 = r8; \
855 goto tjmp3; \
856 tjmp2: \
857 *(u64 *)(r10 - 8) = r9; \
858 *(u64 *)(r10 - 16) = r9; \
859 r1 = r8; \
860 r1 += 8; \
861 r2 = 0; \
862 r3 = 0; \
863 r4 = r10; \
864 r4 += -16; \
865 call %[bpf_dynptr_from_mem]; \
866 tjmp3: \
867 r1 = r10; \
868 r1 += -16; \
869 r2 = 0; \
870 call %[bpf_ringbuf_discard_dynptr]; "
871 :
872 : __imm(bpf_map_update_elem),
873 __imm(bpf_map_lookup_elem),
874 __imm(bpf_ringbuf_reserve_dynptr),
875 __imm(bpf_dynptr_from_mem),
876 __imm(bpf_ringbuf_discard_dynptr),
877 __imm_addr(array_map4),
878 __imm_addr(ringbuf)
879 : __clobber_all
880 );
881 return 0;
882 }
883
884 SEC("?tc")
885 __failure __msg("dynptr has to be at a constant offset") __log_level(2)
dynptr_var_off_overwrite(struct __sk_buff * ctx)886 int dynptr_var_off_overwrite(struct __sk_buff *ctx)
887 {
888 asm volatile (
889 "r9 = 16; \
890 *(u32 *)(r10 - 4) = r9; \
891 r8 = *(u32 *)(r10 - 4); \
892 if r8 >= 0 goto vjmp1; \
893 r0 = 1; \
894 exit; \
895 vjmp1: \
896 if r8 <= 16 goto vjmp2; \
897 r0 = 1; \
898 exit; \
899 vjmp2: \
900 r8 &= 16; \
901 r1 = %[ringbuf] ll; \
902 r2 = 8; \
903 r3 = 0; \
904 r4 = r10; \
905 r4 += -32; \
906 r4 += r8; \
907 call %[bpf_ringbuf_reserve_dynptr]; \
908 r9 = 0xeB9F; \
909 *(u64 *)(r10 - 16) = r9; \
910 r1 = r10; \
911 r1 += -32; \
912 r1 += r8; \
913 r2 = 0; \
914 call %[bpf_ringbuf_discard_dynptr]; "
915 :
916 : __imm(bpf_ringbuf_reserve_dynptr),
917 __imm(bpf_ringbuf_discard_dynptr),
918 __imm_addr(ringbuf)
919 : __clobber_all
920 );
921 return 0;
922 }
923
924 SEC("?tc")
925 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
dynptr_partial_slot_invalidate(struct __sk_buff * ctx)926 int dynptr_partial_slot_invalidate(struct __sk_buff *ctx)
927 {
928 asm volatile (
929 "r6 = %[ringbuf] ll; \
930 r7 = %[array_map4] ll; \
931 r1 = r7; \
932 r2 = r10; \
933 r2 += -8; \
934 r9 = 0; \
935 *(u64 *)(r2 + 0) = r9; \
936 r3 = r2; \
937 r4 = 0; \
938 r8 = r2; \
939 call %[bpf_map_update_elem]; \
940 r1 = r7; \
941 r2 = r8; \
942 call %[bpf_map_lookup_elem]; \
943 if r0 != 0 goto sjmp1; \
944 exit; \
945 sjmp1: \
946 r7 = r0; \
947 r1 = r6; \
948 r2 = 8; \
949 r3 = 0; \
950 r4 = r10; \
951 r4 += -24; \
952 call %[bpf_ringbuf_reserve_dynptr]; \
953 *(u64 *)(r10 - 16) = r9; \
954 r1 = r7; \
955 r2 = 8; \
956 r3 = 0; \
957 r4 = r10; \
958 r4 += -16; \
959 call %[bpf_dynptr_from_mem]; \
960 r1 = r10; \
961 r1 += -512; \
962 r2 = 488; \
963 r3 = r10; \
964 r3 += -24; \
965 r4 = 0; \
966 r5 = 0; \
967 call %[bpf_dynptr_read]; \
968 r8 = 1; \
969 if r0 != 0 goto sjmp2; \
970 r8 = 0; \
971 sjmp2: \
972 r1 = r10; \
973 r1 += -24; \
974 r2 = 0; \
975 call %[bpf_ringbuf_discard_dynptr]; "
976 :
977 : __imm(bpf_map_update_elem),
978 __imm(bpf_map_lookup_elem),
979 __imm(bpf_ringbuf_reserve_dynptr),
980 __imm(bpf_ringbuf_discard_dynptr),
981 __imm(bpf_dynptr_from_mem),
982 __imm(bpf_dynptr_read),
983 __imm_addr(ringbuf),
984 __imm_addr(array_map4)
985 : __clobber_all
986 );
987 return 0;
988 }
989
990 /* Test that it is allowed to overwrite unreferenced dynptr. */
991 SEC("?raw_tp")
992 __success
dynptr_overwrite_unref(void * ctx)993 int dynptr_overwrite_unref(void *ctx)
994 {
995 struct bpf_dynptr ptr;
996
997 if (get_map_val_dynptr(&ptr))
998 return 0;
999 if (get_map_val_dynptr(&ptr))
1000 return 0;
1001 if (get_map_val_dynptr(&ptr))
1002 return 0;
1003
1004 return 0;
1005 }
1006
1007 /* Test that slices are invalidated on reinitializing a dynptr. */
1008 SEC("?raw_tp")
1009 __failure __msg("invalid mem access 'scalar'")
dynptr_invalidate_slice_reinit(void * ctx)1010 int dynptr_invalidate_slice_reinit(void *ctx)
1011 {
1012 struct bpf_dynptr ptr;
1013 __u8 *p;
1014
1015 if (get_map_val_dynptr(&ptr))
1016 return 0;
1017 p = bpf_dynptr_data(&ptr, 0, 1);
1018 if (!p)
1019 return 0;
1020 if (get_map_val_dynptr(&ptr))
1021 return 0;
1022 /* this should fail */
1023 return *p;
1024 }
1025
1026 /* Invalidation of dynptr slices on destruction of dynptr should not miss
1027 * mem_or_null pointers.
1028 */
1029 SEC("?raw_tp")
1030 __failure __msg("R{{[0-9]+}} type=scalar expected=percpu_ptr_")
dynptr_invalidate_slice_or_null(void * ctx)1031 int dynptr_invalidate_slice_or_null(void *ctx)
1032 {
1033 struct bpf_dynptr ptr;
1034 __u8 *p;
1035
1036 if (get_map_val_dynptr(&ptr))
1037 return 0;
1038
1039 p = bpf_dynptr_data(&ptr, 0, 1);
1040 *(__u8 *)&ptr = 0;
1041 /* this should fail */
1042 bpf_this_cpu_ptr(p);
1043 return 0;
1044 }
1045
1046 /* Destruction of dynptr should also any slices obtained from it */
1047 SEC("?raw_tp")
1048 __failure __msg("R{{[0-9]+}} invalid mem access 'scalar'")
dynptr_invalidate_slice_failure(void * ctx)1049 int dynptr_invalidate_slice_failure(void *ctx)
1050 {
1051 struct bpf_dynptr ptr1;
1052 struct bpf_dynptr ptr2;
1053 __u8 *p1, *p2;
1054
1055 if (get_map_val_dynptr(&ptr1))
1056 return 0;
1057 if (get_map_val_dynptr(&ptr2))
1058 return 0;
1059
1060 p1 = bpf_dynptr_data(&ptr1, 0, 1);
1061 if (!p1)
1062 return 0;
1063 p2 = bpf_dynptr_data(&ptr2, 0, 1);
1064 if (!p2)
1065 return 0;
1066
1067 *(__u8 *)&ptr1 = 0;
1068 /* this should fail */
1069 return *p1;
1070 }
1071
1072 /* Invalidation of slices should be scoped and should not prevent dereferencing
1073 * slices of another dynptr after destroying unrelated dynptr
1074 */
1075 SEC("?raw_tp")
1076 __success
dynptr_invalidate_slice_success(void * ctx)1077 int dynptr_invalidate_slice_success(void *ctx)
1078 {
1079 struct bpf_dynptr ptr1;
1080 struct bpf_dynptr ptr2;
1081 __u8 *p1, *p2;
1082
1083 if (get_map_val_dynptr(&ptr1))
1084 return 1;
1085 if (get_map_val_dynptr(&ptr2))
1086 return 1;
1087
1088 p1 = bpf_dynptr_data(&ptr1, 0, 1);
1089 if (!p1)
1090 return 1;
1091 p2 = bpf_dynptr_data(&ptr2, 0, 1);
1092 if (!p2)
1093 return 1;
1094
1095 *(__u8 *)&ptr1 = 0;
1096 return *p2;
1097 }
1098
1099 /* Overwriting referenced dynptr should be rejected */
1100 SEC("?raw_tp")
1101 __failure __msg("cannot overwrite referenced dynptr")
dynptr_overwrite_ref(void * ctx)1102 int dynptr_overwrite_ref(void *ctx)
1103 {
1104 struct bpf_dynptr ptr;
1105
1106 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
1107 /* this should fail */
1108 if (get_map_val_dynptr(&ptr))
1109 bpf_ringbuf_discard_dynptr(&ptr, 0);
1110 return 0;
1111 }
1112
1113 /* Reject writes to dynptr slot from bpf_dynptr_read */
1114 SEC("?raw_tp")
1115 __failure __msg("cannot overwrite referenced dynptr")
dynptr_read_into_slot(void * ctx)1116 int dynptr_read_into_slot(void *ctx)
1117 {
1118 union {
1119 struct {
1120 char _pad[48];
1121 struct bpf_dynptr ptr;
1122 };
1123 char buf[64];
1124 } data;
1125
1126 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &data.ptr);
1127 /* this should fail */
1128 bpf_dynptr_read(data.buf, sizeof(data.buf), &data.ptr, 0, 0);
1129
1130 return 0;
1131 }
1132
1133 /* bpf_dynptr_slice()s are read-only and cannot be written to */
1134 SEC("?tc")
1135 __failure __msg("R{{[0-9]+}} cannot write into rdonly_mem")
skb_invalid_slice_write(struct __sk_buff * skb)1136 int skb_invalid_slice_write(struct __sk_buff *skb)
1137 {
1138 struct bpf_dynptr ptr;
1139 struct ethhdr *hdr;
1140 char buffer[sizeof(*hdr)] = {};
1141
1142 bpf_dynptr_from_skb(skb, 0, &ptr);
1143
1144 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1145 if (!hdr)
1146 return SK_DROP;
1147
1148 /* this should fail */
1149 hdr->h_proto = 1;
1150
1151 return SK_PASS;
1152 }
1153
1154 /* bpf_dynptr_slice()s are read-only and cannot be written to */
1155 SEC("?tc")
1156 __failure __msg("R{{[0-9]+}} cannot write into rdonly_mem")
skb_meta_invalid_slice_write(struct __sk_buff * skb)1157 int skb_meta_invalid_slice_write(struct __sk_buff *skb)
1158 {
1159 struct bpf_dynptr meta;
1160 __u8 *md;
1161
1162 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1163
1164 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md));
1165 if (!md)
1166 return SK_DROP;
1167
1168 /* this should fail */
1169 *md = 42;
1170
1171 return SK_PASS;
1172 }
1173
1174 /* The read-only data slice is invalidated whenever a helper changes packet data */
1175 SEC("?tc")
1176 __failure __msg("invalid mem access 'scalar'")
skb_invalid_data_slice1(struct __sk_buff * skb)1177 int skb_invalid_data_slice1(struct __sk_buff *skb)
1178 {
1179 struct bpf_dynptr ptr;
1180 struct ethhdr *hdr;
1181 char buffer[sizeof(*hdr)] = {};
1182
1183 bpf_dynptr_from_skb(skb, 0, &ptr);
1184
1185 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1186 if (!hdr)
1187 return SK_DROP;
1188
1189 val = hdr->h_proto;
1190
1191 if (bpf_skb_pull_data(skb, skb->len))
1192 return SK_DROP;
1193
1194 /* this should fail */
1195 val = hdr->h_proto;
1196
1197 return SK_PASS;
1198 }
1199
1200 /* The read-write data slice is invalidated whenever a helper changes packet data */
1201 SEC("?tc")
1202 __failure __msg("invalid mem access 'scalar'")
skb_invalid_data_slice2(struct __sk_buff * skb)1203 int skb_invalid_data_slice2(struct __sk_buff *skb)
1204 {
1205 struct bpf_dynptr ptr;
1206 struct ethhdr *hdr;
1207 char buffer[sizeof(*hdr)] = {};
1208
1209 bpf_dynptr_from_skb(skb, 0, &ptr);
1210
1211 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1212 if (!hdr)
1213 return SK_DROP;
1214
1215 hdr->h_proto = 123;
1216
1217 if (bpf_skb_pull_data(skb, skb->len))
1218 return SK_DROP;
1219
1220 /* this should fail */
1221 hdr->h_proto = 1;
1222
1223 return SK_PASS;
1224 }
1225
1226 /* The read-only data slice is invalidated whenever bpf_dynptr_write() is called */
1227 SEC("?tc")
1228 __failure __msg("invalid mem access 'scalar'")
skb_invalid_data_slice3(struct __sk_buff * skb)1229 int skb_invalid_data_slice3(struct __sk_buff *skb)
1230 {
1231 char write_data[64] = "hello there, world!!";
1232 struct bpf_dynptr ptr;
1233 struct ethhdr *hdr;
1234 char buffer[sizeof(*hdr)] = {};
1235
1236 bpf_dynptr_from_skb(skb, 0, &ptr);
1237
1238 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1239 if (!hdr)
1240 return SK_DROP;
1241
1242 val = hdr->h_proto;
1243
1244 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
1245
1246 /* this should fail */
1247 val = hdr->h_proto;
1248
1249 return SK_PASS;
1250 }
1251
1252 /* The read-write data slice is invalidated whenever bpf_dynptr_write() is called */
1253 SEC("?tc")
1254 __failure __msg("invalid mem access 'scalar'")
skb_invalid_data_slice4(struct __sk_buff * skb)1255 int skb_invalid_data_slice4(struct __sk_buff *skb)
1256 {
1257 char write_data[64] = "hello there, world!!";
1258 struct bpf_dynptr ptr;
1259 struct ethhdr *hdr;
1260 char buffer[sizeof(*hdr)] = {};
1261
1262 bpf_dynptr_from_skb(skb, 0, &ptr);
1263 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1264 if (!hdr)
1265 return SK_DROP;
1266
1267 hdr->h_proto = 123;
1268
1269 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
1270
1271 /* this should fail */
1272 hdr->h_proto = 1;
1273
1274 return SK_PASS;
1275 }
1276
1277 /* Read-only skb data slice is invalidated on write to skb metadata */
1278 SEC("?tc")
1279 __failure __msg("invalid mem access 'scalar'")
ro_skb_slice_invalid_after_metadata_write(struct __sk_buff * skb)1280 int ro_skb_slice_invalid_after_metadata_write(struct __sk_buff *skb)
1281 {
1282 struct bpf_dynptr data, meta;
1283 __u8 *d;
1284
1285 bpf_dynptr_from_skb(skb, 0, &data);
1286 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1287
1288 d = bpf_dynptr_slice(&data, 0, NULL, sizeof(*d));
1289 if (!d)
1290 return SK_DROP;
1291
1292 bpf_dynptr_write(&meta, 0, "x", 1, 0);
1293
1294 /* this should fail */
1295 val = *d;
1296
1297 return SK_PASS;
1298 }
1299
1300 /* Read-write skb data slice is invalidated on write to skb metadata */
1301 SEC("?tc")
1302 __failure __msg("invalid mem access 'scalar'")
rw_skb_slice_invalid_after_metadata_write(struct __sk_buff * skb)1303 int rw_skb_slice_invalid_after_metadata_write(struct __sk_buff *skb)
1304 {
1305 struct bpf_dynptr data, meta;
1306 __u8 *d;
1307
1308 bpf_dynptr_from_skb(skb, 0, &data);
1309 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1310
1311 d = bpf_dynptr_slice_rdwr(&data, 0, NULL, sizeof(*d));
1312 if (!d)
1313 return SK_DROP;
1314
1315 bpf_dynptr_write(&meta, 0, "x", 1, 0);
1316
1317 /* this should fail */
1318 *d = 42;
1319
1320 return SK_PASS;
1321 }
1322
1323 /* Read-only skb metadata slice is invalidated on write to skb data */
1324 SEC("?tc")
1325 __failure __msg("invalid mem access 'scalar'")
ro_skb_meta_slice_invalid_after_payload_write(struct __sk_buff * skb)1326 int ro_skb_meta_slice_invalid_after_payload_write(struct __sk_buff *skb)
1327 {
1328 struct bpf_dynptr data, meta;
1329 __u8 *md;
1330
1331 bpf_dynptr_from_skb(skb, 0, &data);
1332 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1333
1334 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md));
1335 if (!md)
1336 return SK_DROP;
1337
1338 bpf_dynptr_write(&data, 0, "x", 1, 0);
1339
1340 /* this should fail */
1341 val = *md;
1342
1343 return SK_PASS;
1344 }
1345
1346 /* Read-write skb metadata slice is invalidated on write to skb data slice */
1347 SEC("?tc")
1348 __failure __msg("invalid mem access 'scalar'")
rw_skb_meta_slice_invalid_after_payload_write(struct __sk_buff * skb)1349 int rw_skb_meta_slice_invalid_after_payload_write(struct __sk_buff *skb)
1350 {
1351 struct bpf_dynptr data, meta;
1352 __u8 *md;
1353
1354 bpf_dynptr_from_skb(skb, 0, &data);
1355 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1356
1357 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md));
1358 if (!md)
1359 return SK_DROP;
1360
1361 bpf_dynptr_write(&data, 0, "x", 1, 0);
1362
1363 /* this should fail */
1364 *md = 42;
1365
1366 return SK_PASS;
1367 }
1368
1369 /* Read-only skb metadata slice is invalidated whenever a helper changes packet data */
1370 SEC("?tc")
1371 __failure __msg("invalid mem access 'scalar'")
ro_skb_meta_slice_invalid_after_payload_helper(struct __sk_buff * skb)1372 int ro_skb_meta_slice_invalid_after_payload_helper(struct __sk_buff *skb)
1373 {
1374 struct bpf_dynptr meta;
1375 __u8 *md;
1376
1377 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1378
1379 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md));
1380 if (!md)
1381 return SK_DROP;
1382
1383 if (bpf_skb_pull_data(skb, skb->len))
1384 return SK_DROP;
1385
1386 /* this should fail */
1387 val = *md;
1388
1389 return SK_PASS;
1390 }
1391
1392 /* Read-write skb metadata slice is invalidated whenever a helper changes packet data */
1393 SEC("?tc")
1394 __failure __msg("invalid mem access 'scalar'")
rw_skb_meta_slice_invalid_after_payload_helper(struct __sk_buff * skb)1395 int rw_skb_meta_slice_invalid_after_payload_helper(struct __sk_buff *skb)
1396 {
1397 struct bpf_dynptr meta;
1398 __u8 *md;
1399
1400 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1401
1402 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md));
1403 if (!md)
1404 return SK_DROP;
1405
1406 if (bpf_skb_pull_data(skb, skb->len))
1407 return SK_DROP;
1408
1409 /* this should fail */
1410 *md = 42;
1411
1412 return SK_PASS;
1413 }
1414
1415 /* Read-only skb metadata slice is invalidated on write to skb metadata */
1416 SEC("?tc")
1417 __failure __msg("invalid mem access 'scalar'")
ro_skb_meta_slice_invalid_after_metadata_write(struct __sk_buff * skb)1418 int ro_skb_meta_slice_invalid_after_metadata_write(struct __sk_buff *skb)
1419 {
1420 struct bpf_dynptr meta;
1421 __u8 *md;
1422
1423 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1424
1425 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md));
1426 if (!md)
1427 return SK_DROP;
1428
1429 bpf_dynptr_write(&meta, 0, "x", 1, 0);
1430
1431 /* this should fail */
1432 val = *md;
1433
1434 return SK_PASS;
1435 }
1436
1437 /* Read-write skb metadata slice is invalidated on write to skb metadata */
1438 SEC("?tc")
1439 __failure __msg("invalid mem access 'scalar'")
rw_skb_meta_slice_invalid_after_metadata_write(struct __sk_buff * skb)1440 int rw_skb_meta_slice_invalid_after_metadata_write(struct __sk_buff *skb)
1441 {
1442 struct bpf_dynptr meta;
1443 __u8 *md;
1444
1445 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1446
1447 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md));
1448 if (!md)
1449 return SK_DROP;
1450
1451 bpf_dynptr_write(&meta, 0, "x", 1, 0);
1452
1453 /* this should fail */
1454 *md = 42;
1455
1456 return SK_PASS;
1457 }
1458
1459 /* The read-only data slice is invalidated whenever a helper changes packet data */
1460 SEC("?xdp")
1461 __failure __msg("invalid mem access 'scalar'")
xdp_invalid_data_slice1(struct xdp_md * xdp)1462 int xdp_invalid_data_slice1(struct xdp_md *xdp)
1463 {
1464 struct bpf_dynptr ptr;
1465 struct ethhdr *hdr;
1466 char buffer[sizeof(*hdr)] = {};
1467
1468 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1469 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1470 if (!hdr)
1471 return SK_DROP;
1472
1473 val = hdr->h_proto;
1474
1475 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1476 return XDP_DROP;
1477
1478 /* this should fail */
1479 val = hdr->h_proto;
1480
1481 return XDP_PASS;
1482 }
1483
1484 /* The read-write data slice is invalidated whenever a helper changes packet data */
1485 SEC("?xdp")
1486 __failure __msg("invalid mem access 'scalar'")
xdp_invalid_data_slice2(struct xdp_md * xdp)1487 int xdp_invalid_data_slice2(struct xdp_md *xdp)
1488 {
1489 struct bpf_dynptr ptr;
1490 struct ethhdr *hdr;
1491 char buffer[sizeof(*hdr)] = {};
1492
1493 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1494 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1495 if (!hdr)
1496 return SK_DROP;
1497
1498 hdr->h_proto = 9;
1499
1500 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1501 return XDP_DROP;
1502
1503 /* this should fail */
1504 hdr->h_proto = 1;
1505
1506 return XDP_PASS;
1507 }
1508
1509 /* Only supported prog type can create skb-type dynptrs */
1510 SEC("?xdp")
1511 __failure __msg("calling kernel function bpf_dynptr_from_skb is not allowed")
skb_invalid_ctx(void * ctx)1512 int skb_invalid_ctx(void *ctx)
1513 {
1514 struct bpf_dynptr ptr;
1515
1516 /* this should fail */
1517 bpf_dynptr_from_skb(ctx, 0, &ptr);
1518
1519 return 0;
1520 }
1521
1522 /* Only supported prog type can create skb_meta-type dynptrs */
1523 SEC("?raw_tp")
1524 __failure __msg("calling kernel function bpf_dynptr_from_skb_meta is not allowed")
skb_meta_invalid_ctx(void * ctx)1525 int skb_meta_invalid_ctx(void *ctx)
1526 {
1527 struct bpf_dynptr meta;
1528
1529 /* this should fail */
1530 bpf_dynptr_from_skb_meta(ctx, 0, &meta);
1531
1532 return 0;
1533 }
1534
1535 SEC("fentry/skb_tx_error")
1536 __failure __msg("must be referenced or trusted")
BPF_PROG(skb_invalid_ctx_fentry,void * skb)1537 int BPF_PROG(skb_invalid_ctx_fentry, void *skb)
1538 {
1539 struct bpf_dynptr ptr;
1540
1541 /* this should fail */
1542 bpf_dynptr_from_skb(skb, 0, &ptr);
1543
1544 return 0;
1545 }
1546
1547 SEC("fexit/skb_tx_error")
1548 __failure __msg("must be referenced or trusted")
BPF_PROG(skb_invalid_ctx_fexit,void * skb)1549 int BPF_PROG(skb_invalid_ctx_fexit, void *skb)
1550 {
1551 struct bpf_dynptr ptr;
1552
1553 /* this should fail */
1554 bpf_dynptr_from_skb(skb, 0, &ptr);
1555
1556 return 0;
1557 }
1558
1559 /* Reject writes to dynptr slot for uninit arg */
1560 SEC("?raw_tp")
1561 __failure __msg("cannot overwrite referenced dynptr")
uninit_write_into_slot(void * ctx)1562 int uninit_write_into_slot(void *ctx)
1563 {
1564 struct {
1565 char buf[64];
1566 struct bpf_dynptr ptr;
1567 } data;
1568
1569 bpf_ringbuf_reserve_dynptr(&ringbuf, 80, 0, &data.ptr);
1570 /* this should fail */
1571 bpf_get_current_comm(data.buf, 80);
1572
1573 return 0;
1574 }
1575
1576 /* Only supported prog type can create xdp-type dynptrs */
1577 SEC("?raw_tp")
1578 __failure __msg("calling kernel function bpf_dynptr_from_xdp is not allowed")
xdp_invalid_ctx(void * ctx)1579 int xdp_invalid_ctx(void *ctx)
1580 {
1581 struct bpf_dynptr ptr;
1582
1583 /* this should fail */
1584 bpf_dynptr_from_xdp(ctx, 0, &ptr);
1585
1586 return 0;
1587 }
1588
1589 __u32 hdr_size = sizeof(struct ethhdr);
1590 /* Can't pass in variable-sized len to bpf_dynptr_slice */
1591 SEC("?tc")
1592 __failure __msg("must be a known constant")
1593 __msg("requires this memory size to be a verifier-known constant")
dynptr_slice_var_len1(struct __sk_buff * skb)1594 int dynptr_slice_var_len1(struct __sk_buff *skb)
1595 {
1596 struct bpf_dynptr ptr;
1597 struct ethhdr *hdr;
1598 char buffer[sizeof(*hdr)] = {};
1599
1600 bpf_dynptr_from_skb(skb, 0, &ptr);
1601
1602 /* this should fail */
1603 hdr = bpf_dynptr_slice(&ptr, 0, buffer, hdr_size);
1604 if (!hdr)
1605 return SK_DROP;
1606
1607 return SK_PASS;
1608 }
1609
1610 /* Can't pass in variable-sized len to bpf_dynptr_slice */
1611 SEC("?tc")
1612 __failure __msg("must be a known constant")
1613 __msg("requires this memory size to be a verifier-known constant")
dynptr_slice_var_len2(struct __sk_buff * skb)1614 int dynptr_slice_var_len2(struct __sk_buff *skb)
1615 {
1616 char buffer[sizeof(struct ethhdr)] = {};
1617 struct bpf_dynptr ptr;
1618 struct ethhdr *hdr;
1619
1620 bpf_dynptr_from_skb(skb, 0, &ptr);
1621
1622 if (hdr_size <= sizeof(buffer)) {
1623 /* this should fail */
1624 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, hdr_size);
1625 if (!hdr)
1626 return SK_DROP;
1627 hdr->h_proto = 12;
1628 }
1629
1630 return SK_PASS;
1631 }
1632
callback(__u32 index,void * data)1633 static int callback(__u32 index, void *data)
1634 {
1635 *(__u32 *)data = 123;
1636
1637 return 0;
1638 }
1639
1640 /* A commuted add should preserve the parent id of a dynptr data slice. */
1641 SEC("?raw_tp")
1642 __failure __msg("invalid mem access 'scalar'")
dynptr_slice_commuted_invalidate(void * ctx)1643 int dynptr_slice_commuted_invalidate(void *ctx)
1644 {
1645 struct bpf_dynptr ptr;
1646 __u32 *slice, *derived;
1647
1648 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(__u32), 0, &ptr);
1649
1650 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
1651 if (!slice)
1652 goto done;
1653
1654 asm volatile ("%[dst] = 0;"
1655 "%[dst] += %[src];"
1656 "%[src] = 0;"
1657 : [dst]"=&r"(derived), [src]"+r"(slice)
1658 :
1659 : "memory");
1660
1661 bpf_ringbuf_discard_dynptr(&ptr, 0);
1662 val = *derived;
1663 return 0;
1664
1665 done:
1666 bpf_ringbuf_discard_dynptr(&ptr, 0);
1667 return 0;
1668 }
1669
1670 /* If the dynptr is written into in a callback function, its data
1671 * slices should be invalidated as well.
1672 */
1673 SEC("?raw_tp")
1674 __failure __msg("invalid mem access 'scalar'")
invalid_data_slices(void * ctx)1675 int invalid_data_slices(void *ctx)
1676 {
1677 struct bpf_dynptr ptr;
1678 __u32 *slice;
1679
1680 if (get_map_val_dynptr(&ptr))
1681 return 0;
1682
1683 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
1684 if (!slice)
1685 return 0;
1686
1687 bpf_loop(10, callback, &ptr, 0);
1688
1689 /* this should fail */
1690 *slice = 1;
1691
1692 return 0;
1693 }
1694
1695 /* Program types that don't allow writes to packet data should fail if
1696 * bpf_dynptr_slice_rdwr is called
1697 */
1698 SEC("cgroup_skb/ingress")
1699 __failure __msg("the prog does not allow writes to packet data")
invalid_slice_rdwr_rdonly(struct __sk_buff * skb)1700 int invalid_slice_rdwr_rdonly(struct __sk_buff *skb)
1701 {
1702 char buffer[sizeof(struct ethhdr)] = {};
1703 struct bpf_dynptr ptr;
1704 struct ethhdr *hdr;
1705
1706 bpf_dynptr_from_skb(skb, 0, &ptr);
1707
1708 /* this should fail since cgroup_skb doesn't allow
1709 * changing packet data
1710 */
1711 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1712 __sink(hdr);
1713
1714 return 0;
1715 }
1716
1717 /* bpf_dynptr_adjust can only be called on initialized dynptrs */
1718 SEC("?raw_tp")
1719 __failure __msg("Expected an initialized dynptr as R1")
dynptr_adjust_invalid(void * ctx)1720 int dynptr_adjust_invalid(void *ctx)
1721 {
1722 struct bpf_dynptr ptr = {};
1723
1724 /* this should fail */
1725 bpf_dynptr_adjust(&ptr, 1, 2);
1726
1727 return 0;
1728 }
1729
1730 /* bpf_dynptr_is_null can only be called on initialized dynptrs */
1731 SEC("?raw_tp")
1732 __failure __msg("Expected an initialized dynptr as R1")
dynptr_is_null_invalid(void * ctx)1733 int dynptr_is_null_invalid(void *ctx)
1734 {
1735 struct bpf_dynptr ptr = {};
1736
1737 /* this should fail */
1738 bpf_dynptr_is_null(&ptr);
1739
1740 return 0;
1741 }
1742
1743 /* bpf_dynptr_is_rdonly can only be called on initialized dynptrs */
1744 SEC("?raw_tp")
1745 __failure __msg("Expected an initialized dynptr as R1")
dynptr_is_rdonly_invalid(void * ctx)1746 int dynptr_is_rdonly_invalid(void *ctx)
1747 {
1748 struct bpf_dynptr ptr = {};
1749
1750 /* this should fail */
1751 bpf_dynptr_is_rdonly(&ptr);
1752
1753 return 0;
1754 }
1755
1756 /* bpf_dynptr_size can only be called on initialized dynptrs */
1757 SEC("?raw_tp")
1758 __failure __msg("Expected an initialized dynptr as R1")
dynptr_size_invalid(void * ctx)1759 int dynptr_size_invalid(void *ctx)
1760 {
1761 struct bpf_dynptr ptr = {};
1762
1763 /* this should fail */
1764 bpf_dynptr_size(&ptr);
1765
1766 return 0;
1767 }
1768
1769 /* Only initialized dynptrs can be cloned */
1770 SEC("?raw_tp")
1771 __failure __msg("Expected an initialized dynptr as R1")
clone_invalid1(void * ctx)1772 int clone_invalid1(void *ctx)
1773 {
1774 struct bpf_dynptr ptr1 = {};
1775 struct bpf_dynptr ptr2;
1776
1777 /* this should fail */
1778 bpf_dynptr_clone(&ptr1, &ptr2);
1779
1780 return 0;
1781 }
1782
1783 /* Can't overwrite an existing dynptr when cloning */
1784 SEC("?xdp")
1785 __failure __msg("cannot overwrite referenced dynptr")
clone_invalid2(struct xdp_md * xdp)1786 int clone_invalid2(struct xdp_md *xdp)
1787 {
1788 struct bpf_dynptr ptr1;
1789 struct bpf_dynptr clone;
1790
1791 bpf_dynptr_from_xdp(xdp, 0, &ptr1);
1792
1793 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &clone);
1794
1795 /* this should fail */
1796 bpf_dynptr_clone(&ptr1, &clone);
1797
1798 bpf_ringbuf_submit_dynptr(&clone, 0);
1799
1800 return 0;
1801 }
1802
1803 /* Invalidating a dynptr should invalidate its clones */
1804 SEC("?raw_tp")
1805 __failure __msg("Expected an initialized dynptr as R3")
clone_invalidate1(void * ctx)1806 int clone_invalidate1(void *ctx)
1807 {
1808 struct bpf_dynptr clone;
1809 struct bpf_dynptr ptr;
1810 char read_data[64];
1811
1812 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1813
1814 bpf_dynptr_clone(&ptr, &clone);
1815
1816 bpf_ringbuf_submit_dynptr(&ptr, 0);
1817
1818 /* this should fail */
1819 bpf_dynptr_read(read_data, sizeof(read_data), &clone, 0, 0);
1820
1821 return 0;
1822 }
1823
1824 /* Invalidating a dynptr should invalidate its parent */
1825 SEC("?raw_tp")
1826 __failure __msg("Expected an initialized dynptr as R3")
clone_invalidate2(void * ctx)1827 int clone_invalidate2(void *ctx)
1828 {
1829 struct bpf_dynptr ptr;
1830 struct bpf_dynptr clone;
1831 char read_data[64];
1832
1833 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1834
1835 bpf_dynptr_clone(&ptr, &clone);
1836
1837 bpf_ringbuf_submit_dynptr(&clone, 0);
1838
1839 /* this should fail */
1840 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
1841
1842 return 0;
1843 }
1844
1845 /* Invalidating a dynptr should invalidate its siblings */
1846 SEC("?raw_tp")
1847 __failure __msg("Expected an initialized dynptr as R3")
clone_invalidate3(void * ctx)1848 int clone_invalidate3(void *ctx)
1849 {
1850 struct bpf_dynptr ptr;
1851 struct bpf_dynptr clone1;
1852 struct bpf_dynptr clone2;
1853 char read_data[64];
1854
1855 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1856
1857 bpf_dynptr_clone(&ptr, &clone1);
1858
1859 bpf_dynptr_clone(&ptr, &clone2);
1860
1861 bpf_ringbuf_submit_dynptr(&clone2, 0);
1862
1863 /* this should fail */
1864 bpf_dynptr_read(read_data, sizeof(read_data), &clone1, 0, 0);
1865
1866 return 0;
1867 }
1868
1869 /* Invalidating a dynptr should invalidate any data slices
1870 * of its clones
1871 */
1872 SEC("?raw_tp")
1873 __failure __msg("invalid mem access 'scalar'")
clone_invalidate4(void * ctx)1874 int clone_invalidate4(void *ctx)
1875 {
1876 struct bpf_dynptr ptr;
1877 struct bpf_dynptr clone;
1878 int *data;
1879
1880 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1881
1882 bpf_dynptr_clone(&ptr, &clone);
1883 data = bpf_dynptr_data(&clone, 0, sizeof(val));
1884 if (!data)
1885 return 0;
1886
1887 bpf_ringbuf_submit_dynptr(&ptr, 0);
1888
1889 /* this should fail */
1890 *data = 123;
1891
1892 return 0;
1893 }
1894
1895 /* Invalidating a dynptr should invalidate any data slices
1896 * of its parent
1897 */
1898 SEC("?raw_tp")
1899 __failure __msg("invalid mem access 'scalar'")
clone_invalidate5(void * ctx)1900 int clone_invalidate5(void *ctx)
1901 {
1902 struct bpf_dynptr ptr;
1903 struct bpf_dynptr clone;
1904 int *data;
1905
1906 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1907 data = bpf_dynptr_data(&ptr, 0, sizeof(val));
1908 if (!data)
1909 return 0;
1910
1911 bpf_dynptr_clone(&ptr, &clone);
1912
1913 bpf_ringbuf_submit_dynptr(&clone, 0);
1914
1915 /* this should fail */
1916 *data = 123;
1917
1918 return 0;
1919 }
1920
1921 /* Invalidating a dynptr should invalidate any data slices
1922 * of its sibling
1923 */
1924 SEC("?raw_tp")
1925 __failure __msg("invalid mem access 'scalar'")
clone_invalidate6(void * ctx)1926 int clone_invalidate6(void *ctx)
1927 {
1928 struct bpf_dynptr ptr;
1929 struct bpf_dynptr clone1;
1930 struct bpf_dynptr clone2;
1931 int *data;
1932
1933 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1934
1935 bpf_dynptr_clone(&ptr, &clone1);
1936
1937 bpf_dynptr_clone(&ptr, &clone2);
1938
1939 data = bpf_dynptr_data(&clone1, 0, sizeof(val));
1940 if (!data)
1941 return 0;
1942
1943 bpf_ringbuf_submit_dynptr(&clone2, 0);
1944
1945 /* this should fail */
1946 *data = 123;
1947
1948 return 0;
1949 }
1950
1951 /* A skb clone's data slices should be invalid anytime packet data changes */
1952 SEC("?tc")
1953 __failure __msg("invalid mem access 'scalar'")
clone_skb_packet_data(struct __sk_buff * skb)1954 int clone_skb_packet_data(struct __sk_buff *skb)
1955 {
1956 char buffer[sizeof(__u32)] = {};
1957 struct bpf_dynptr clone;
1958 struct bpf_dynptr ptr;
1959 __u32 *data;
1960
1961 bpf_dynptr_from_skb(skb, 0, &ptr);
1962
1963 bpf_dynptr_clone(&ptr, &clone);
1964 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer));
1965 if (!data)
1966 return XDP_DROP;
1967
1968 if (bpf_skb_pull_data(skb, skb->len))
1969 return SK_DROP;
1970
1971 /* this should fail */
1972 *data = 123;
1973
1974 return 0;
1975 }
1976
1977 /* A skb clone's metadata slice becomes invalid anytime packet data changes */
1978 SEC("?tc")
1979 __failure __msg("invalid mem access 'scalar'")
clone_skb_packet_meta(struct __sk_buff * skb)1980 int clone_skb_packet_meta(struct __sk_buff *skb)
1981 {
1982 struct bpf_dynptr clone, meta;
1983 __u8 *md;
1984
1985 bpf_dynptr_from_skb_meta(skb, 0, &meta);
1986 bpf_dynptr_clone(&meta, &clone);
1987 md = bpf_dynptr_slice_rdwr(&clone, 0, NULL, sizeof(*md));
1988 if (!md)
1989 return SK_DROP;
1990
1991 if (bpf_skb_pull_data(skb, skb->len))
1992 return SK_DROP;
1993
1994 /* this should fail */
1995 *md = 42;
1996
1997 return 0;
1998 }
1999
2000 /* A xdp clone's data slices should be invalid anytime packet data changes */
2001 SEC("?xdp")
2002 __failure __msg("invalid mem access 'scalar'")
clone_xdp_packet_data(struct xdp_md * xdp)2003 int clone_xdp_packet_data(struct xdp_md *xdp)
2004 {
2005 char buffer[sizeof(__u32)] = {};
2006 struct bpf_dynptr clone;
2007 struct bpf_dynptr ptr;
2008 struct ethhdr *hdr;
2009 __u32 *data;
2010
2011 bpf_dynptr_from_xdp(xdp, 0, &ptr);
2012
2013 bpf_dynptr_clone(&ptr, &clone);
2014 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer));
2015 if (!data)
2016 return XDP_DROP;
2017
2018 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
2019 return XDP_DROP;
2020
2021 /* this should fail */
2022 *data = 123;
2023
2024 return 0;
2025 }
2026
2027 /* Buffers that are provided must be sufficiently long */
2028 SEC("?cgroup_skb/egress")
2029 __failure __msg("memory, len pair leads to invalid memory access")
test_dynptr_skb_small_buff(struct __sk_buff * skb)2030 int test_dynptr_skb_small_buff(struct __sk_buff *skb)
2031 {
2032 struct bpf_dynptr ptr;
2033 char buffer[8] = {};
2034 __u64 *data;
2035
2036 if (bpf_dynptr_from_skb(skb, 0, &ptr)) {
2037 err = 1;
2038 return 1;
2039 }
2040
2041 /* This may return NULL. SKB may require a buffer */
2042 data = bpf_dynptr_slice(&ptr, 0, buffer, 9);
2043
2044 return !!data;
2045 }
2046
global_call_bpf_dynptr(const struct bpf_dynptr * dynptr)2047 __noinline long global_call_bpf_dynptr(const struct bpf_dynptr *dynptr)
2048 {
2049 long ret = 0;
2050 /* Avoid leaving this global function empty to avoid having the compiler
2051 * optimize away the call to this global function.
2052 */
2053 __sink(ret);
2054 return ret;
2055 }
2056
2057 SEC("?raw_tp")
2058 __failure __msg("R1 expected pointer to stack or const struct bpf_dynptr")
test_dynptr_reg_type(void * ctx)2059 int test_dynptr_reg_type(void *ctx)
2060 {
2061 struct task_struct *current = NULL;
2062 /* R1 should be holding a PTR_TO_BTF_ID, so this shouldn't be a
2063 * reg->type that can be passed to a function accepting a
2064 * ARG_PTR_TO_DYNPTR | MEM_RDONLY. process_dynptr_func() should catch
2065 * this.
2066 */
2067 global_call_bpf_dynptr((const struct bpf_dynptr *)current);
2068 return 0;
2069 }
2070
2071 /* Overwriting a referenced dynptr is allowed if a clone still holds the ref */
2072 SEC("?raw_tp")
2073 __success
dynptr_overwrite_ref_with_clone(void * ctx)2074 int dynptr_overwrite_ref_with_clone(void *ctx)
2075 {
2076 struct bpf_dynptr ptr, clone;
2077
2078 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
2079
2080 bpf_dynptr_clone(&ptr, &clone);
2081
2082 /* Overwrite the original - clone still holds the ref */
2083 *(volatile __u8 *)&ptr = 0;
2084
2085 bpf_ringbuf_discard_dynptr(&clone, 0);
2086
2087 return 0;
2088 }
2089
2090 /* Overwriting the last referenced dynptr should still be rejected */
2091 SEC("?raw_tp")
2092 __failure __msg("cannot overwrite referenced dynptr")
dynptr_overwrite_ref_last_clone(void * ctx)2093 int dynptr_overwrite_ref_last_clone(void *ctx)
2094 {
2095 struct bpf_dynptr ptr, clone;
2096
2097 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
2098
2099 bpf_dynptr_clone(&ptr, &clone);
2100
2101 /* Overwrite the original - clone still holds the ref, OK */
2102 *(volatile __u8 *)&ptr = 0;
2103
2104 /* Overwrite the last holder - this should fail */
2105 *(volatile __u8 *)&clone = 0;
2106
2107 return 0;
2108 }
2109
2110 /* Overwriting a clone should be allowed if the original still holds the ref */
2111 SEC("?raw_tp")
2112 __success
dynptr_overwrite_clone_with_original(void * ctx)2113 int dynptr_overwrite_clone_with_original(void *ctx)
2114 {
2115 struct bpf_dynptr ptr, clone;
2116
2117 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
2118
2119 bpf_dynptr_clone(&ptr, &clone);
2120
2121 /* Overwrite the clone - original still holds the ref */
2122 *(volatile __u8 *)&clone = 0;
2123
2124 bpf_ringbuf_discard_dynptr(&ptr, 0);
2125
2126 return 0;
2127 }
2128
2129 /* Data slices from the destroyed dynptr should be invalidated */
2130 SEC("?raw_tp")
2131 __failure __msg("invalid mem access 'scalar'")
dynptr_overwrite_ref_invalidate_slice(void * ctx)2132 int dynptr_overwrite_ref_invalidate_slice(void *ctx)
2133 {
2134 struct bpf_dynptr ptr, clone;
2135 int *data;
2136
2137 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
2138
2139 data = bpf_dynptr_data(&ptr, 0, sizeof(val));
2140 if (!data)
2141 return 0;
2142
2143 bpf_dynptr_clone(&ptr, &clone);
2144
2145 /* Overwrite the original - clone holds the ref */
2146 *(volatile __u8 *)&ptr = 0;
2147
2148 /* data was from the original dynptr, should be invalid now */
2149 *data = 123;
2150
2151 return 0;
2152 }
2153
2154 /*
2155 * Data slices from a dynptr clone should remain valid after
2156 * overwriting the original dynptr
2157 */
2158 SEC("?raw_tp")
2159 __success
dynptr_overwrite_ref_clone_slice_valid(void * ctx)2160 int dynptr_overwrite_ref_clone_slice_valid(void *ctx)
2161 {
2162 struct bpf_dynptr ptr, clone;
2163 int *data;
2164
2165 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
2166
2167 bpf_dynptr_clone(&ptr, &clone);
2168
2169 data = bpf_dynptr_data(&clone, 0, sizeof(val));
2170 if (!data) {
2171 bpf_ringbuf_discard_dynptr(&clone, 0);
2172 return 0;
2173 }
2174
2175 /* Overwrite the original - clone holds the ref */
2176 *(volatile __u8 *)&ptr = 0;
2177
2178 /* data is from the clone, should still be valid */
2179 *data = 123;
2180
2181 bpf_ringbuf_discard_dynptr(&clone, 0);
2182
2183 return 0;
2184 }
2185