xref: /linux/tools/testing/selftests/bpf/progs/dynptr_fail.c (revision 5a8cd539ac19f7a68e68e1d25ef9ca2ff55b8500)
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