1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Facebook */
7 #include <bpf/bpf_helpers.h>
8 #include <linux/if_ether.h>
10 #include "bpf_kfuncs.h"
12 char _license[] SEC("license") = "GPL";
16 struct bpf_dynptr ptr;
20 __uint(type, BPF_MAP_TYPE_ARRAY);
21 __uint(max_entries, 1);
23 __type(value, struct bpf_dynptr);
24 } array_map1 SEC(".maps");
27 __uint(type, BPF_MAP_TYPE_ARRAY);
28 __uint(max_entries, 1);
30 __type(value, struct test_info);
31 } array_map2 SEC(".maps");
34 __uint(type, BPF_MAP_TYPE_ARRAY);
35 __uint(max_entries, 1);
38 } array_map3 SEC(".maps");
41 __uint(type, BPF_MAP_TYPE_ARRAY);
42 __uint(max_entries, 1);
45 } array_map4 SEC(".maps");
54 __uint(type, BPF_MAP_TYPE_RINGBUF);
55 __uint(max_entries, 4096);
56 } ringbuf SEC(".maps");
60 static int get_map_val_dynptr(struct bpf_dynptr *ptr)
62 __u32 key = 0, *map_val;
64 bpf_map_update_elem(&array_map3, &key, &val, 0);
66 map_val = bpf_map_lookup_elem(&array_map3, &key);
70 bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr);
75 /* Every bpf_ringbuf_reserve_dynptr call must have a corresponding
76 * bpf_ringbuf_submit/discard_dynptr call
79 __failure __msg("Unreleased reference id=2")
80 int ringbuf_missing_release1(void *ctx)
82 struct bpf_dynptr ptr;
84 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
86 /* missing a call to bpf_ringbuf_discard/submit_dynptr */
92 __failure __msg("Unreleased reference id=4")
93 int ringbuf_missing_release2(void *ctx)
95 struct bpf_dynptr ptr1, ptr2;
96 struct sample *sample;
98 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1);
99 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
101 sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample));
103 bpf_ringbuf_discard_dynptr(&ptr1, 0);
104 bpf_ringbuf_discard_dynptr(&ptr2, 0);
108 bpf_ringbuf_submit_dynptr(&ptr1, 0);
110 /* missing a call to bpf_ringbuf_discard/submit_dynptr on ptr2 */
115 static int missing_release_callback_fn(__u32 index, void *data)
117 struct bpf_dynptr ptr;
119 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
121 /* missing a call to bpf_ringbuf_discard/submit_dynptr */
126 /* Any dynptr initialized within a callback must have bpf_dynptr_put called */
128 __failure __msg("Unreleased reference id")
129 int ringbuf_missing_release_callback(void *ctx)
131 bpf_loop(10, missing_release_callback_fn, NULL, 0);
135 /* Can't call bpf_ringbuf_submit/discard_dynptr on a non-initialized dynptr */
137 __failure __msg("arg 1 is an unacquired reference")
138 int ringbuf_release_uninit_dynptr(void *ctx)
140 struct bpf_dynptr ptr;
142 /* this should fail */
143 bpf_ringbuf_submit_dynptr(&ptr, 0);
148 /* A dynptr can't be used after it has been invalidated */
150 __failure __msg("Expected an initialized dynptr as arg #3")
151 int use_after_invalid(void *ctx)
153 struct bpf_dynptr ptr;
156 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr);
158 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
160 bpf_ringbuf_submit_dynptr(&ptr, 0);
162 /* this should fail */
163 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
168 /* Can't call non-dynptr ringbuf APIs on a dynptr ringbuf sample */
170 __failure __msg("type=mem expected=ringbuf_mem")
171 int ringbuf_invalid_api(void *ctx)
173 struct bpf_dynptr ptr;
174 struct sample *sample;
176 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
177 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
183 /* invalid API use. need to use dynptr API to submit/discard */
184 bpf_ringbuf_submit(sample, 0);
187 bpf_ringbuf_discard_dynptr(&ptr, 0);
191 /* Can't add a dynptr to a map */
193 __failure __msg("invalid indirect read from stack")
194 int add_dynptr_to_map1(void *ctx)
196 struct bpf_dynptr ptr;
199 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
201 /* this should fail */
202 bpf_map_update_elem(&array_map1, &key, &ptr, 0);
204 bpf_ringbuf_submit_dynptr(&ptr, 0);
209 /* Can't add a struct with an embedded dynptr to a map */
211 __failure __msg("invalid indirect read from stack")
212 int add_dynptr_to_map2(void *ctx)
217 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr);
219 /* this should fail */
220 bpf_map_update_elem(&array_map2, &key, &x, 0);
222 bpf_ringbuf_submit_dynptr(&x.ptr, 0);
227 /* A data slice can't be accessed out of bounds */
229 __failure __msg("value is outside of the allowed memory range")
230 int data_slice_out_of_bounds_ringbuf(void *ctx)
232 struct bpf_dynptr ptr;
235 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
237 data = bpf_dynptr_data(&ptr, 0, 8);
241 /* can't index out of bounds of the data slice */
242 val = *((char *)data + 8);
245 bpf_ringbuf_submit_dynptr(&ptr, 0);
249 /* A data slice can't be accessed out of bounds */
251 __failure __msg("value is outside of the allowed memory range")
252 int data_slice_out_of_bounds_skb(struct __sk_buff *skb)
254 struct bpf_dynptr ptr;
256 char buffer[sizeof(*hdr)] = {};
258 bpf_dynptr_from_skb(skb, 0, &ptr);
260 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
264 /* this should fail */
265 *(__u8*)(hdr + 1) = 1;
271 __failure __msg("value is outside of the allowed memory range")
272 int data_slice_out_of_bounds_map_value(void *ctx)
275 struct bpf_dynptr ptr;
278 get_map_val_dynptr(&ptr);
280 data = bpf_dynptr_data(&ptr, 0, sizeof(map_val));
284 /* can't index out of bounds of the data slice */
285 val = *((char *)data + (sizeof(map_val) + 1));
290 /* A data slice can't be used after it has been released */
292 __failure __msg("invalid mem access 'scalar'")
293 int data_slice_use_after_release1(void *ctx)
295 struct bpf_dynptr ptr;
296 struct sample *sample;
298 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
299 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
305 bpf_ringbuf_submit_dynptr(&ptr, 0);
307 /* this should fail */
313 bpf_ringbuf_discard_dynptr(&ptr, 0);
317 /* A data slice can't be used after it has been released.
319 * This tests the case where the data slice tracks a dynptr (ptr2)
320 * that is at a non-zero offset from the frame pointer (ptr1 is at fp,
321 * ptr2 is at fp - 16).
324 __failure __msg("invalid mem access 'scalar'")
325 int data_slice_use_after_release2(void *ctx)
327 struct bpf_dynptr ptr1, ptr2;
328 struct sample *sample;
330 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr1);
331 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
333 sample = bpf_dynptr_data(&ptr2, 0, sizeof(*sample));
339 bpf_ringbuf_submit_dynptr(&ptr2, 0);
341 /* this should fail */
344 bpf_ringbuf_submit_dynptr(&ptr1, 0);
349 bpf_ringbuf_discard_dynptr(&ptr2, 0);
350 bpf_ringbuf_discard_dynptr(&ptr1, 0);
354 /* A data slice must be first checked for NULL */
356 __failure __msg("invalid mem access 'mem_or_null'")
357 int data_slice_missing_null_check1(void *ctx)
359 struct bpf_dynptr ptr;
362 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
364 data = bpf_dynptr_data(&ptr, 0, 8);
366 /* missing if (!data) check */
368 /* this should fail */
371 bpf_ringbuf_submit_dynptr(&ptr, 0);
375 /* A data slice can't be dereferenced if it wasn't checked for null */
377 __failure __msg("invalid mem access 'mem_or_null'")
378 int data_slice_missing_null_check2(void *ctx)
380 struct bpf_dynptr ptr;
381 __u64 *data1, *data2;
383 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
385 data1 = bpf_dynptr_data(&ptr, 0, 8);
386 data2 = bpf_dynptr_data(&ptr, 0, 8);
388 /* this should fail */
391 bpf_ringbuf_discard_dynptr(&ptr, 0);
395 /* Can't pass in a dynptr as an arg to a helper function that doesn't take in a
399 __failure __msg("invalid indirect read from stack")
400 int invalid_helper1(void *ctx)
402 struct bpf_dynptr ptr;
404 get_map_val_dynptr(&ptr);
406 /* this should fail */
407 bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!");
412 /* A dynptr can't be passed into a helper function at a non-zero offset */
414 __failure __msg("cannot pass in dynptr at an offset=-8")
415 int invalid_helper2(void *ctx)
417 struct bpf_dynptr ptr;
420 get_map_val_dynptr(&ptr);
422 /* this should fail */
423 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0);
427 /* A bpf_dynptr is invalidated if it's been written into */
429 __failure __msg("Expected an initialized dynptr as arg #1")
430 int invalid_write1(void *ctx)
432 struct bpf_dynptr ptr;
436 get_map_val_dynptr(&ptr);
438 memcpy(&ptr, &x, sizeof(x));
440 /* this should fail */
441 data = bpf_dynptr_data(&ptr, 0, 1);
448 * A bpf_dynptr can't be used as a dynptr if it has been written into at a fixed
452 __failure __msg("cannot overwrite referenced dynptr")
453 int invalid_write2(void *ctx)
455 struct bpf_dynptr ptr;
459 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
461 memcpy((void *)&ptr + 8, &x, sizeof(x));
463 /* this should fail */
464 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
466 bpf_ringbuf_submit_dynptr(&ptr, 0);
472 * A bpf_dynptr can't be used as a dynptr if it has been written into at a
476 __failure __msg("cannot overwrite referenced dynptr")
477 int invalid_write3(void *ctx)
479 struct bpf_dynptr ptr;
484 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
486 memcpy(stack_buf, &val, sizeof(val));
487 len = stack_buf[0] & 0xf;
489 memcpy((void *)&ptr + len, &x, sizeof(x));
491 /* this should fail */
492 bpf_ringbuf_submit_dynptr(&ptr, 0);
497 static int invalid_write4_callback(__u32 index, void *data)
499 *(__u32 *)data = 123;
504 /* If the dynptr is written into in a callback function, it should
505 * be invalidated as a dynptr
508 __failure __msg("cannot overwrite referenced dynptr")
509 int invalid_write4(void *ctx)
511 struct bpf_dynptr ptr;
513 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
515 bpf_loop(10, invalid_write4_callback, &ptr, 0);
517 /* this should fail */
518 bpf_ringbuf_submit_dynptr(&ptr, 0);
523 /* A globally-defined bpf_dynptr can't be used (it must reside as a stack frame) */
524 struct bpf_dynptr global_dynptr;
527 __failure __msg("type=map_value expected=fp")
528 int global(void *ctx)
530 /* this should fail */
531 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr);
533 bpf_ringbuf_discard_dynptr(&global_dynptr, 0);
538 /* A direct read should fail */
540 __failure __msg("invalid read from stack")
541 int invalid_read1(void *ctx)
543 struct bpf_dynptr ptr;
545 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
547 /* this should fail */
550 bpf_ringbuf_discard_dynptr(&ptr, 0);
555 /* A direct read at an offset should fail */
557 __failure __msg("cannot pass in dynptr at an offset")
558 int invalid_read2(void *ctx)
560 struct bpf_dynptr ptr;
563 get_map_val_dynptr(&ptr);
565 /* this should fail */
566 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0);
571 /* A direct read at an offset into the lower stack slot should fail */
573 __failure __msg("invalid read from stack")
574 int invalid_read3(void *ctx)
576 struct bpf_dynptr ptr1, ptr2;
578 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1);
579 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2);
581 /* this should fail */
582 memcpy(&val, (void *)&ptr1 + 8, sizeof(val));
584 bpf_ringbuf_discard_dynptr(&ptr1, 0);
585 bpf_ringbuf_discard_dynptr(&ptr2, 0);
590 static int invalid_read4_callback(__u32 index, void *data)
592 /* this should fail */
593 val = *(__u32 *)data;
598 /* A direct read within a callback function should fail */
600 __failure __msg("invalid read from stack")
601 int invalid_read4(void *ctx)
603 struct bpf_dynptr ptr;
605 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
607 bpf_loop(10, invalid_read4_callback, &ptr, 0);
609 bpf_ringbuf_submit_dynptr(&ptr, 0);
614 /* Initializing a dynptr on an offset should fail */
616 __failure __msg("cannot pass in dynptr at an offset=0")
617 int invalid_offset(void *ctx)
619 struct bpf_dynptr ptr;
621 /* this should fail */
622 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1);
624 bpf_ringbuf_discard_dynptr(&ptr, 0);
629 /* Can't release a dynptr twice */
631 __failure __msg("arg 1 is an unacquired reference")
632 int release_twice(void *ctx)
634 struct bpf_dynptr ptr;
636 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
638 bpf_ringbuf_discard_dynptr(&ptr, 0);
640 /* this second release should fail */
641 bpf_ringbuf_discard_dynptr(&ptr, 0);
646 static int release_twice_callback_fn(__u32 index, void *data)
648 /* this should fail */
649 bpf_ringbuf_discard_dynptr(data, 0);
654 /* Test that releasing a dynptr twice, where one of the releases happens
655 * within a callback function, fails
658 __failure __msg("arg 1 is an unacquired reference")
659 int release_twice_callback(void *ctx)
661 struct bpf_dynptr ptr;
663 bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr);
665 bpf_ringbuf_discard_dynptr(&ptr, 0);
667 bpf_loop(10, release_twice_callback_fn, &ptr, 0);
672 /* Reject unsupported local mem types for dynptr_from_mem API */
674 __failure __msg("Unsupported reg type fp for bpf_dynptr_from_mem data")
675 int dynptr_from_mem_invalid_api(void *ctx)
677 struct bpf_dynptr ptr;
680 /* this should fail */
681 bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr);
687 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
688 int dynptr_pruning_overwrite(struct __sk_buff *ctx)
692 r6 = %[ringbuf] ll; \
698 call %[bpf_ringbuf_reserve_dynptr]; \
699 if r0 == 0 goto pjmp1; \
702 *(u64 *)(r10 - 16) = r9; \
707 call %[bpf_ringbuf_discard_dynptr]; "
709 : __imm(bpf_ringbuf_reserve_dynptr),
710 __imm(bpf_ringbuf_discard_dynptr),
718 __success __msg("12: safe") __log_level(2)
719 int dynptr_pruning_stacksafe(struct __sk_buff *ctx)
723 r6 = %[ringbuf] ll; \
729 call %[bpf_ringbuf_reserve_dynptr]; \
730 if r0 == 0 goto stjmp1; \
738 call %[bpf_ringbuf_discard_dynptr]; "
740 : __imm(bpf_ringbuf_reserve_dynptr),
741 __imm(bpf_ringbuf_discard_dynptr),
749 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
750 int dynptr_pruning_type_confusion(struct __sk_buff *ctx)
753 "r6 = %[array_map4] ll; \
754 r7 = %[ringbuf] ll; \
759 *(u64 *)(r2 + 0) = r9; \
763 *(u64 *)(r10 - 16) = r9; \
764 *(u64 *)(r10 - 24) = r9; \
768 call %[bpf_map_update_elem]; \
771 call %[bpf_map_lookup_elem]; \
772 if r0 != 0 goto tjmp1; \
781 r0 = *(u64 *)(r0 + 0); \
782 call %[bpf_ringbuf_reserve_dynptr]; \
783 if r0 == 0 goto tjmp2; \
793 *(u64 *)(r10 - 8) = r9; \
794 *(u64 *)(r10 - 16) = r9; \
801 call %[bpf_dynptr_from_mem]; \
806 call %[bpf_ringbuf_discard_dynptr]; "
808 : __imm(bpf_map_update_elem),
809 __imm(bpf_map_lookup_elem),
810 __imm(bpf_ringbuf_reserve_dynptr),
811 __imm(bpf_dynptr_from_mem),
812 __imm(bpf_ringbuf_discard_dynptr),
813 __imm_addr(array_map4),
821 __failure __msg("dynptr has to be at a constant offset") __log_level(2)
822 int dynptr_var_off_overwrite(struct __sk_buff *ctx)
826 *(u32 *)(r10 - 4) = r9; \
827 r8 = *(u32 *)(r10 - 4); \
828 if r8 >= 0 goto vjmp1; \
832 if r8 <= 16 goto vjmp2; \
837 r1 = %[ringbuf] ll; \
843 call %[bpf_ringbuf_reserve_dynptr]; \
845 *(u64 *)(r10 - 16) = r9; \
850 call %[bpf_ringbuf_discard_dynptr]; "
852 : __imm(bpf_ringbuf_reserve_dynptr),
853 __imm(bpf_ringbuf_discard_dynptr),
861 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
862 int dynptr_partial_slot_invalidate(struct __sk_buff *ctx)
865 "r6 = %[ringbuf] ll; \
866 r7 = %[array_map4] ll; \
871 *(u64 *)(r2 + 0) = r9; \
875 call %[bpf_map_update_elem]; \
878 call %[bpf_map_lookup_elem]; \
879 if r0 != 0 goto sjmp1; \
888 call %[bpf_ringbuf_reserve_dynptr]; \
889 *(u64 *)(r10 - 16) = r9; \
895 call %[bpf_dynptr_from_mem]; \
903 call %[bpf_dynptr_read]; \
905 if r0 != 0 goto sjmp2; \
911 call %[bpf_ringbuf_discard_dynptr]; "
913 : __imm(bpf_map_update_elem),
914 __imm(bpf_map_lookup_elem),
915 __imm(bpf_ringbuf_reserve_dynptr),
916 __imm(bpf_ringbuf_discard_dynptr),
917 __imm(bpf_dynptr_from_mem),
918 __imm(bpf_dynptr_read),
920 __imm_addr(array_map4)
926 /* Test that it is allowed to overwrite unreferenced dynptr. */
929 int dynptr_overwrite_unref(void *ctx)
931 struct bpf_dynptr ptr;
933 if (get_map_val_dynptr(&ptr))
935 if (get_map_val_dynptr(&ptr))
937 if (get_map_val_dynptr(&ptr))
943 /* Test that slices are invalidated on reinitializing a dynptr. */
945 __failure __msg("invalid mem access 'scalar'")
946 int dynptr_invalidate_slice_reinit(void *ctx)
948 struct bpf_dynptr ptr;
951 if (get_map_val_dynptr(&ptr))
953 p = bpf_dynptr_data(&ptr, 0, 1);
956 if (get_map_val_dynptr(&ptr))
958 /* this should fail */
962 /* Invalidation of dynptr slices on destruction of dynptr should not miss
963 * mem_or_null pointers.
966 __failure __msg("R1 type=scalar expected=percpu_ptr_")
967 int dynptr_invalidate_slice_or_null(void *ctx)
969 struct bpf_dynptr ptr;
972 if (get_map_val_dynptr(&ptr))
975 p = bpf_dynptr_data(&ptr, 0, 1);
977 /* this should fail */
982 /* Destruction of dynptr should also any slices obtained from it */
984 __failure __msg("R7 invalid mem access 'scalar'")
985 int dynptr_invalidate_slice_failure(void *ctx)
987 struct bpf_dynptr ptr1;
988 struct bpf_dynptr ptr2;
991 if (get_map_val_dynptr(&ptr1))
993 if (get_map_val_dynptr(&ptr2))
996 p1 = bpf_dynptr_data(&ptr1, 0, 1);
999 p2 = bpf_dynptr_data(&ptr2, 0, 1);
1004 /* this should fail */
1008 /* Invalidation of slices should be scoped and should not prevent dereferencing
1009 * slices of another dynptr after destroying unrelated dynptr
1013 int dynptr_invalidate_slice_success(void *ctx)
1015 struct bpf_dynptr ptr1;
1016 struct bpf_dynptr ptr2;
1019 if (get_map_val_dynptr(&ptr1))
1021 if (get_map_val_dynptr(&ptr2))
1024 p1 = bpf_dynptr_data(&ptr1, 0, 1);
1027 p2 = bpf_dynptr_data(&ptr2, 0, 1);
1035 /* Overwriting referenced dynptr should be rejected */
1037 __failure __msg("cannot overwrite referenced dynptr")
1038 int dynptr_overwrite_ref(void *ctx)
1040 struct bpf_dynptr ptr;
1042 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
1043 /* this should fail */
1044 if (get_map_val_dynptr(&ptr))
1045 bpf_ringbuf_discard_dynptr(&ptr, 0);
1049 /* Reject writes to dynptr slot from bpf_dynptr_read */
1051 __failure __msg("potential write to dynptr at off=-16")
1052 int dynptr_read_into_slot(void *ctx)
1057 struct bpf_dynptr ptr;
1062 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &data.ptr);
1063 /* this should fail */
1064 bpf_dynptr_read(data.buf, sizeof(data.buf), &data.ptr, 0, 0);
1069 /* bpf_dynptr_slice()s are read-only and cannot be written to */
1071 __failure __msg("R0 cannot write into rdonly_mem")
1072 int skb_invalid_slice_write(struct __sk_buff *skb)
1074 struct bpf_dynptr ptr;
1076 char buffer[sizeof(*hdr)] = {};
1078 bpf_dynptr_from_skb(skb, 0, &ptr);
1080 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1084 /* this should fail */
1090 /* The read-only data slice is invalidated whenever a helper changes packet data */
1092 __failure __msg("invalid mem access 'scalar'")
1093 int skb_invalid_data_slice1(struct __sk_buff *skb)
1095 struct bpf_dynptr ptr;
1097 char buffer[sizeof(*hdr)] = {};
1099 bpf_dynptr_from_skb(skb, 0, &ptr);
1101 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1107 if (bpf_skb_pull_data(skb, skb->len))
1110 /* this should fail */
1116 /* The read-write data slice is invalidated whenever a helper changes packet data */
1118 __failure __msg("invalid mem access 'scalar'")
1119 int skb_invalid_data_slice2(struct __sk_buff *skb)
1121 struct bpf_dynptr ptr;
1123 char buffer[sizeof(*hdr)] = {};
1125 bpf_dynptr_from_skb(skb, 0, &ptr);
1127 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1133 if (bpf_skb_pull_data(skb, skb->len))
1136 /* this should fail */
1142 /* The read-only data slice is invalidated whenever bpf_dynptr_write() is called */
1144 __failure __msg("invalid mem access 'scalar'")
1145 int skb_invalid_data_slice3(struct __sk_buff *skb)
1147 char write_data[64] = "hello there, world!!";
1148 struct bpf_dynptr ptr;
1150 char buffer[sizeof(*hdr)] = {};
1152 bpf_dynptr_from_skb(skb, 0, &ptr);
1154 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1160 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
1162 /* this should fail */
1168 /* The read-write data slice is invalidated whenever bpf_dynptr_write() is called */
1170 __failure __msg("invalid mem access 'scalar'")
1171 int skb_invalid_data_slice4(struct __sk_buff *skb)
1173 char write_data[64] = "hello there, world!!";
1174 struct bpf_dynptr ptr;
1176 char buffer[sizeof(*hdr)] = {};
1178 bpf_dynptr_from_skb(skb, 0, &ptr);
1179 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1185 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
1187 /* this should fail */
1193 /* The read-only data slice is invalidated whenever a helper changes packet data */
1195 __failure __msg("invalid mem access 'scalar'")
1196 int xdp_invalid_data_slice1(struct xdp_md *xdp)
1198 struct bpf_dynptr ptr;
1200 char buffer[sizeof(*hdr)] = {};
1202 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1203 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1209 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1212 /* this should fail */
1218 /* The read-write data slice is invalidated whenever a helper changes packet data */
1220 __failure __msg("invalid mem access 'scalar'")
1221 int xdp_invalid_data_slice2(struct xdp_md *xdp)
1223 struct bpf_dynptr ptr;
1225 char buffer[sizeof(*hdr)] = {};
1227 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1228 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1234 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1237 /* this should fail */
1243 /* Only supported prog type can create skb-type dynptrs */
1245 __failure __msg("calling kernel function bpf_dynptr_from_skb is not allowed")
1246 int skb_invalid_ctx(void *ctx)
1248 struct bpf_dynptr ptr;
1250 /* this should fail */
1251 bpf_dynptr_from_skb(ctx, 0, &ptr);
1256 /* Reject writes to dynptr slot for uninit arg */
1258 __failure __msg("potential write to dynptr at off=-16")
1259 int uninit_write_into_slot(void *ctx)
1263 struct bpf_dynptr ptr;
1266 bpf_ringbuf_reserve_dynptr(&ringbuf, 80, 0, &data.ptr);
1267 /* this should fail */
1268 bpf_get_current_comm(data.buf, 80);
1273 /* Only supported prog type can create xdp-type dynptrs */
1275 __failure __msg("calling kernel function bpf_dynptr_from_xdp is not allowed")
1276 int xdp_invalid_ctx(void *ctx)
1278 struct bpf_dynptr ptr;
1280 /* this should fail */
1281 bpf_dynptr_from_xdp(ctx, 0, &ptr);
1286 __u32 hdr_size = sizeof(struct ethhdr);
1287 /* Can't pass in variable-sized len to bpf_dynptr_slice */
1289 __failure __msg("unbounded memory access")
1290 int dynptr_slice_var_len1(struct __sk_buff *skb)
1292 struct bpf_dynptr ptr;
1294 char buffer[sizeof(*hdr)] = {};
1296 bpf_dynptr_from_skb(skb, 0, &ptr);
1298 /* this should fail */
1299 hdr = bpf_dynptr_slice(&ptr, 0, buffer, hdr_size);
1306 /* Can't pass in variable-sized len to bpf_dynptr_slice */
1308 __failure __msg("must be a known constant")
1309 int dynptr_slice_var_len2(struct __sk_buff *skb)
1311 char buffer[sizeof(struct ethhdr)] = {};
1312 struct bpf_dynptr ptr;
1315 bpf_dynptr_from_skb(skb, 0, &ptr);
1317 if (hdr_size <= sizeof(buffer)) {
1318 /* this should fail */
1319 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, hdr_size);
1328 static int callback(__u32 index, void *data)
1330 *(__u32 *)data = 123;
1335 /* If the dynptr is written into in a callback function, its data
1336 * slices should be invalidated as well.
1339 __failure __msg("invalid mem access 'scalar'")
1340 int invalid_data_slices(void *ctx)
1342 struct bpf_dynptr ptr;
1345 if (get_map_val_dynptr(&ptr))
1348 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
1352 bpf_loop(10, callback, &ptr, 0);
1354 /* this should fail */
1360 /* Program types that don't allow writes to packet data should fail if
1361 * bpf_dynptr_slice_rdwr is called
1363 SEC("cgroup_skb/ingress")
1364 __failure __msg("the prog does not allow writes to packet data")
1365 int invalid_slice_rdwr_rdonly(struct __sk_buff *skb)
1367 char buffer[sizeof(struct ethhdr)] = {};
1368 struct bpf_dynptr ptr;
1371 bpf_dynptr_from_skb(skb, 0, &ptr);
1373 /* this should fail since cgroup_skb doesn't allow
1374 * changing packet data
1376 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));