1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Facebook */
8 #include <bpf/bpf_helpers.h>
9 #include <linux/if_ether.h>
11 #include "bpf_kfuncs.h"
13 char _license[] SEC("license") = "GPL";
17 struct bpf_dynptr ptr;
21 __uint(type, BPF_MAP_TYPE_ARRAY);
22 __uint(max_entries, 1);
24 __type(value, struct bpf_dynptr);
25 } array_map1 SEC(".maps");
28 __uint(type, BPF_MAP_TYPE_ARRAY);
29 __uint(max_entries, 1);
31 __type(value, struct test_info);
32 } array_map2 SEC(".maps");
35 __uint(type, BPF_MAP_TYPE_ARRAY);
36 __uint(max_entries, 1);
39 } array_map3 SEC(".maps");
42 __uint(type, BPF_MAP_TYPE_ARRAY);
43 __uint(max_entries, 1);
46 } array_map4 SEC(".maps");
55 __uint(type, BPF_MAP_TYPE_RINGBUF);
56 __uint(max_entries, 4096);
57 } ringbuf SEC(".maps");
61 static int get_map_val_dynptr(struct bpf_dynptr *ptr)
63 __u32 key = 0, *map_val;
65 bpf_map_update_elem(&array_map3, &key, &val, 0);
67 map_val = bpf_map_lookup_elem(&array_map3, &key);
71 bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr);
76 /* Every bpf_ringbuf_reserve_dynptr call must have a corresponding
77 * bpf_ringbuf_submit/discard_dynptr call
80 __failure __msg("Unreleased reference id=2")
81 int ringbuf_missing_release1(void *ctx)
83 struct bpf_dynptr ptr;
85 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
87 /* missing a call to bpf_ringbuf_discard/submit_dynptr */
93 __failure __msg("Unreleased reference id=4")
94 int ringbuf_missing_release2(void *ctx)
96 struct bpf_dynptr ptr1, ptr2;
97 struct sample *sample;
99 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1);
100 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
102 sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample));
104 bpf_ringbuf_discard_dynptr(&ptr1, 0);
105 bpf_ringbuf_discard_dynptr(&ptr2, 0);
109 bpf_ringbuf_submit_dynptr(&ptr1, 0);
111 /* missing a call to bpf_ringbuf_discard/submit_dynptr on ptr2 */
116 static int missing_release_callback_fn(__u32 index, void *data)
118 struct bpf_dynptr ptr;
120 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
122 /* missing a call to bpf_ringbuf_discard/submit_dynptr */
127 /* Any dynptr initialized within a callback must have bpf_dynptr_put called */
129 __failure __msg("Unreleased reference id")
130 int ringbuf_missing_release_callback(void *ctx)
132 bpf_loop(10, missing_release_callback_fn, NULL, 0);
136 /* Can't call bpf_ringbuf_submit/discard_dynptr on a non-initialized dynptr */
138 __failure __msg("arg 1 is an unacquired reference")
139 int ringbuf_release_uninit_dynptr(void *ctx)
141 struct bpf_dynptr ptr;
143 /* this should fail */
144 bpf_ringbuf_submit_dynptr(&ptr, 0);
149 /* A dynptr can't be used after it has been invalidated */
151 __failure __msg("Expected an initialized dynptr as arg #3")
152 int use_after_invalid(void *ctx)
154 struct bpf_dynptr ptr;
157 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr);
159 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
161 bpf_ringbuf_submit_dynptr(&ptr, 0);
163 /* this should fail */
164 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
169 /* Can't call non-dynptr ringbuf APIs on a dynptr ringbuf sample */
171 __failure __msg("type=mem expected=ringbuf_mem")
172 int ringbuf_invalid_api(void *ctx)
174 struct bpf_dynptr ptr;
175 struct sample *sample;
177 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
178 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
184 /* invalid API use. need to use dynptr API to submit/discard */
185 bpf_ringbuf_submit(sample, 0);
188 bpf_ringbuf_discard_dynptr(&ptr, 0);
192 /* Can't add a dynptr to a map */
194 __failure __msg("invalid indirect read from stack")
195 int add_dynptr_to_map1(void *ctx)
197 struct bpf_dynptr ptr;
200 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
202 /* this should fail */
203 bpf_map_update_elem(&array_map1, &key, &ptr, 0);
205 bpf_ringbuf_submit_dynptr(&ptr, 0);
210 /* Can't add a struct with an embedded dynptr to a map */
212 __failure __msg("invalid indirect read from stack")
213 int add_dynptr_to_map2(void *ctx)
218 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr);
220 /* this should fail */
221 bpf_map_update_elem(&array_map2, &key, &x, 0);
223 bpf_ringbuf_submit_dynptr(&x.ptr, 0);
228 /* A data slice can't be accessed out of bounds */
230 __failure __msg("value is outside of the allowed memory range")
231 int data_slice_out_of_bounds_ringbuf(void *ctx)
233 struct bpf_dynptr ptr;
236 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
238 data = bpf_dynptr_data(&ptr, 0, 8);
242 /* can't index out of bounds of the data slice */
243 val = *((char *)data + 8);
246 bpf_ringbuf_submit_dynptr(&ptr, 0);
250 /* A data slice can't be accessed out of bounds */
252 __failure __msg("value is outside of the allowed memory range")
253 int data_slice_out_of_bounds_skb(struct __sk_buff *skb)
255 struct bpf_dynptr ptr;
257 char buffer[sizeof(*hdr)] = {};
259 bpf_dynptr_from_skb(skb, 0, &ptr);
261 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
265 /* this should fail */
266 *(__u8*)(hdr + 1) = 1;
272 __failure __msg("value is outside of the allowed memory range")
273 int data_slice_out_of_bounds_map_value(void *ctx)
276 struct bpf_dynptr ptr;
279 get_map_val_dynptr(&ptr);
281 data = bpf_dynptr_data(&ptr, 0, sizeof(map_val));
285 /* can't index out of bounds of the data slice */
286 val = *((char *)data + (sizeof(map_val) + 1));
291 /* A data slice can't be used after it has been released */
293 __failure __msg("invalid mem access 'scalar'")
294 int data_slice_use_after_release1(void *ctx)
296 struct bpf_dynptr ptr;
297 struct sample *sample;
299 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
300 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
306 bpf_ringbuf_submit_dynptr(&ptr, 0);
308 /* this should fail */
314 bpf_ringbuf_discard_dynptr(&ptr, 0);
318 /* A data slice can't be used after it has been released.
320 * This tests the case where the data slice tracks a dynptr (ptr2)
321 * that is at a non-zero offset from the frame pointer (ptr1 is at fp,
322 * ptr2 is at fp - 16).
325 __failure __msg("invalid mem access 'scalar'")
326 int data_slice_use_after_release2(void *ctx)
328 struct bpf_dynptr ptr1, ptr2;
329 struct sample *sample;
331 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr1);
332 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
334 sample = bpf_dynptr_data(&ptr2, 0, sizeof(*sample));
340 bpf_ringbuf_submit_dynptr(&ptr2, 0);
342 /* this should fail */
345 bpf_ringbuf_submit_dynptr(&ptr1, 0);
350 bpf_ringbuf_discard_dynptr(&ptr2, 0);
351 bpf_ringbuf_discard_dynptr(&ptr1, 0);
355 /* A data slice must be first checked for NULL */
357 __failure __msg("invalid mem access 'mem_or_null'")
358 int data_slice_missing_null_check1(void *ctx)
360 struct bpf_dynptr ptr;
363 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
365 data = bpf_dynptr_data(&ptr, 0, 8);
367 /* missing if (!data) check */
369 /* this should fail */
372 bpf_ringbuf_submit_dynptr(&ptr, 0);
376 /* A data slice can't be dereferenced if it wasn't checked for null */
378 __failure __msg("invalid mem access 'mem_or_null'")
379 int data_slice_missing_null_check2(void *ctx)
381 struct bpf_dynptr ptr;
382 __u64 *data1, *data2;
384 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
386 data1 = bpf_dynptr_data(&ptr, 0, 8);
387 data2 = bpf_dynptr_data(&ptr, 0, 8);
389 /* this should fail */
392 bpf_ringbuf_discard_dynptr(&ptr, 0);
396 /* Can't pass in a dynptr as an arg to a helper function that doesn't take in a
400 __failure __msg("invalid indirect read from stack")
401 int invalid_helper1(void *ctx)
403 struct bpf_dynptr ptr;
405 get_map_val_dynptr(&ptr);
407 /* this should fail */
408 bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!");
413 /* A dynptr can't be passed into a helper function at a non-zero offset */
415 __failure __msg("cannot pass in dynptr at an offset=-8")
416 int invalid_helper2(void *ctx)
418 struct bpf_dynptr ptr;
421 get_map_val_dynptr(&ptr);
423 /* this should fail */
424 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0);
428 /* A bpf_dynptr is invalidated if it's been written into */
430 __failure __msg("Expected an initialized dynptr as arg #1")
431 int invalid_write1(void *ctx)
433 struct bpf_dynptr ptr;
437 get_map_val_dynptr(&ptr);
439 memcpy(&ptr, &x, sizeof(x));
441 /* this should fail */
442 data = bpf_dynptr_data(&ptr, 0, 1);
449 * A bpf_dynptr can't be used as a dynptr if it has been written into at a fixed
453 __failure __msg("cannot overwrite referenced dynptr")
454 int invalid_write2(void *ctx)
456 struct bpf_dynptr ptr;
460 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
462 memcpy((void *)&ptr + 8, &x, sizeof(x));
464 /* this should fail */
465 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
467 bpf_ringbuf_submit_dynptr(&ptr, 0);
473 * A bpf_dynptr can't be used as a dynptr if it has been written into at a
477 __failure __msg("cannot overwrite referenced dynptr")
478 int invalid_write3(void *ctx)
480 struct bpf_dynptr ptr;
485 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
487 memcpy(stack_buf, &val, sizeof(val));
488 len = stack_buf[0] & 0xf;
490 memcpy((void *)&ptr + len, &x, sizeof(x));
492 /* this should fail */
493 bpf_ringbuf_submit_dynptr(&ptr, 0);
498 static int invalid_write4_callback(__u32 index, void *data)
500 *(__u32 *)data = 123;
505 /* If the dynptr is written into in a callback function, it should
506 * be invalidated as a dynptr
509 __failure __msg("cannot overwrite referenced dynptr")
510 int invalid_write4(void *ctx)
512 struct bpf_dynptr ptr;
514 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
516 bpf_loop(10, invalid_write4_callback, &ptr, 0);
518 /* this should fail */
519 bpf_ringbuf_submit_dynptr(&ptr, 0);
524 /* A globally-defined bpf_dynptr can't be used (it must reside as a stack frame) */
525 struct bpf_dynptr global_dynptr;
528 __failure __msg("type=map_value expected=fp")
529 int global(void *ctx)
531 /* this should fail */
532 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr);
534 bpf_ringbuf_discard_dynptr(&global_dynptr, 0);
539 /* A direct read should fail */
541 __failure __msg("invalid read from stack")
542 int invalid_read1(void *ctx)
544 struct bpf_dynptr ptr;
546 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
548 /* this should fail */
551 bpf_ringbuf_discard_dynptr(&ptr, 0);
556 /* A direct read at an offset should fail */
558 __failure __msg("cannot pass in dynptr at an offset")
559 int invalid_read2(void *ctx)
561 struct bpf_dynptr ptr;
564 get_map_val_dynptr(&ptr);
566 /* this should fail */
567 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0);
572 /* A direct read at an offset into the lower stack slot should fail */
574 __failure __msg("invalid read from stack")
575 int invalid_read3(void *ctx)
577 struct bpf_dynptr ptr1, ptr2;
579 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1);
580 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2);
582 /* this should fail */
583 memcpy(&val, (void *)&ptr1 + 8, sizeof(val));
585 bpf_ringbuf_discard_dynptr(&ptr1, 0);
586 bpf_ringbuf_discard_dynptr(&ptr2, 0);
591 static int invalid_read4_callback(__u32 index, void *data)
593 /* this should fail */
594 val = *(__u32 *)data;
599 /* A direct read within a callback function should fail */
601 __failure __msg("invalid read from stack")
602 int invalid_read4(void *ctx)
604 struct bpf_dynptr ptr;
606 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
608 bpf_loop(10, invalid_read4_callback, &ptr, 0);
610 bpf_ringbuf_submit_dynptr(&ptr, 0);
615 /* Initializing a dynptr on an offset should fail */
617 __failure __msg("cannot pass in dynptr at an offset=0")
618 int invalid_offset(void *ctx)
620 struct bpf_dynptr ptr;
622 /* this should fail */
623 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1);
625 bpf_ringbuf_discard_dynptr(&ptr, 0);
630 /* Can't release a dynptr twice */
632 __failure __msg("arg 1 is an unacquired reference")
633 int release_twice(void *ctx)
635 struct bpf_dynptr ptr;
637 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
639 bpf_ringbuf_discard_dynptr(&ptr, 0);
641 /* this second release should fail */
642 bpf_ringbuf_discard_dynptr(&ptr, 0);
647 static int release_twice_callback_fn(__u32 index, void *data)
649 /* this should fail */
650 bpf_ringbuf_discard_dynptr(data, 0);
655 /* Test that releasing a dynptr twice, where one of the releases happens
656 * within a callback function, fails
659 __failure __msg("arg 1 is an unacquired reference")
660 int release_twice_callback(void *ctx)
662 struct bpf_dynptr ptr;
664 bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr);
666 bpf_ringbuf_discard_dynptr(&ptr, 0);
668 bpf_loop(10, release_twice_callback_fn, &ptr, 0);
673 /* Reject unsupported local mem types for dynptr_from_mem API */
675 __failure __msg("Unsupported reg type fp for bpf_dynptr_from_mem data")
676 int dynptr_from_mem_invalid_api(void *ctx)
678 struct bpf_dynptr ptr;
681 /* this should fail */
682 bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr);
688 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
689 int dynptr_pruning_overwrite(struct __sk_buff *ctx)
693 r6 = %[ringbuf] ll; \
699 call %[bpf_ringbuf_reserve_dynptr]; \
700 if r0 == 0 goto pjmp1; \
703 *(u64 *)(r10 - 16) = r9; \
708 call %[bpf_ringbuf_discard_dynptr]; "
710 : __imm(bpf_ringbuf_reserve_dynptr),
711 __imm(bpf_ringbuf_discard_dynptr),
719 __success __msg("12: safe") __log_level(2)
720 int dynptr_pruning_stacksafe(struct __sk_buff *ctx)
724 r6 = %[ringbuf] ll; \
730 call %[bpf_ringbuf_reserve_dynptr]; \
731 if r0 == 0 goto stjmp1; \
739 call %[bpf_ringbuf_discard_dynptr]; "
741 : __imm(bpf_ringbuf_reserve_dynptr),
742 __imm(bpf_ringbuf_discard_dynptr),
750 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
751 int dynptr_pruning_type_confusion(struct __sk_buff *ctx)
754 "r6 = %[array_map4] ll; \
755 r7 = %[ringbuf] ll; \
760 *(u64 *)(r2 + 0) = r9; \
764 *(u64 *)(r10 - 16) = r9; \
765 *(u64 *)(r10 - 24) = r9; \
769 call %[bpf_map_update_elem]; \
772 call %[bpf_map_lookup_elem]; \
773 if r0 != 0 goto tjmp1; \
782 r0 = *(u64 *)(r0 + 0); \
783 call %[bpf_ringbuf_reserve_dynptr]; \
784 if r0 == 0 goto tjmp2; \
794 *(u64 *)(r10 - 8) = r9; \
795 *(u64 *)(r10 - 16) = r9; \
802 call %[bpf_dynptr_from_mem]; \
807 call %[bpf_ringbuf_discard_dynptr]; "
809 : __imm(bpf_map_update_elem),
810 __imm(bpf_map_lookup_elem),
811 __imm(bpf_ringbuf_reserve_dynptr),
812 __imm(bpf_dynptr_from_mem),
813 __imm(bpf_ringbuf_discard_dynptr),
814 __imm_addr(array_map4),
822 __failure __msg("dynptr has to be at a constant offset") __log_level(2)
823 int dynptr_var_off_overwrite(struct __sk_buff *ctx)
827 *(u32 *)(r10 - 4) = r9; \
828 r8 = *(u32 *)(r10 - 4); \
829 if r8 >= 0 goto vjmp1; \
833 if r8 <= 16 goto vjmp2; \
838 r1 = %[ringbuf] ll; \
844 call %[bpf_ringbuf_reserve_dynptr]; \
846 *(u64 *)(r10 - 16) = r9; \
851 call %[bpf_ringbuf_discard_dynptr]; "
853 : __imm(bpf_ringbuf_reserve_dynptr),
854 __imm(bpf_ringbuf_discard_dynptr),
862 __failure __msg("cannot overwrite referenced dynptr") __log_level(2)
863 int dynptr_partial_slot_invalidate(struct __sk_buff *ctx)
866 "r6 = %[ringbuf] ll; \
867 r7 = %[array_map4] ll; \
872 *(u64 *)(r2 + 0) = r9; \
876 call %[bpf_map_update_elem]; \
879 call %[bpf_map_lookup_elem]; \
880 if r0 != 0 goto sjmp1; \
889 call %[bpf_ringbuf_reserve_dynptr]; \
890 *(u64 *)(r10 - 16) = r9; \
896 call %[bpf_dynptr_from_mem]; \
904 call %[bpf_dynptr_read]; \
906 if r0 != 0 goto sjmp2; \
912 call %[bpf_ringbuf_discard_dynptr]; "
914 : __imm(bpf_map_update_elem),
915 __imm(bpf_map_lookup_elem),
916 __imm(bpf_ringbuf_reserve_dynptr),
917 __imm(bpf_ringbuf_discard_dynptr),
918 __imm(bpf_dynptr_from_mem),
919 __imm(bpf_dynptr_read),
921 __imm_addr(array_map4)
927 /* Test that it is allowed to overwrite unreferenced dynptr. */
930 int dynptr_overwrite_unref(void *ctx)
932 struct bpf_dynptr ptr;
934 if (get_map_val_dynptr(&ptr))
936 if (get_map_val_dynptr(&ptr))
938 if (get_map_val_dynptr(&ptr))
944 /* Test that slices are invalidated on reinitializing a dynptr. */
946 __failure __msg("invalid mem access 'scalar'")
947 int dynptr_invalidate_slice_reinit(void *ctx)
949 struct bpf_dynptr ptr;
952 if (get_map_val_dynptr(&ptr))
954 p = bpf_dynptr_data(&ptr, 0, 1);
957 if (get_map_val_dynptr(&ptr))
959 /* this should fail */
963 /* Invalidation of dynptr slices on destruction of dynptr should not miss
964 * mem_or_null pointers.
967 __failure __msg("R1 type=scalar expected=percpu_ptr_")
968 int dynptr_invalidate_slice_or_null(void *ctx)
970 struct bpf_dynptr ptr;
973 if (get_map_val_dynptr(&ptr))
976 p = bpf_dynptr_data(&ptr, 0, 1);
978 /* this should fail */
983 /* Destruction of dynptr should also any slices obtained from it */
985 __failure __msg("R7 invalid mem access 'scalar'")
986 int dynptr_invalidate_slice_failure(void *ctx)
988 struct bpf_dynptr ptr1;
989 struct bpf_dynptr ptr2;
992 if (get_map_val_dynptr(&ptr1))
994 if (get_map_val_dynptr(&ptr2))
997 p1 = bpf_dynptr_data(&ptr1, 0, 1);
1000 p2 = bpf_dynptr_data(&ptr2, 0, 1);
1005 /* this should fail */
1009 /* Invalidation of slices should be scoped and should not prevent dereferencing
1010 * slices of another dynptr after destroying unrelated dynptr
1014 int dynptr_invalidate_slice_success(void *ctx)
1016 struct bpf_dynptr ptr1;
1017 struct bpf_dynptr ptr2;
1020 if (get_map_val_dynptr(&ptr1))
1022 if (get_map_val_dynptr(&ptr2))
1025 p1 = bpf_dynptr_data(&ptr1, 0, 1);
1028 p2 = bpf_dynptr_data(&ptr2, 0, 1);
1036 /* Overwriting referenced dynptr should be rejected */
1038 __failure __msg("cannot overwrite referenced dynptr")
1039 int dynptr_overwrite_ref(void *ctx)
1041 struct bpf_dynptr ptr;
1043 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
1044 /* this should fail */
1045 if (get_map_val_dynptr(&ptr))
1046 bpf_ringbuf_discard_dynptr(&ptr, 0);
1050 /* Reject writes to dynptr slot from bpf_dynptr_read */
1052 __failure __msg("potential write to dynptr at off=-16")
1053 int dynptr_read_into_slot(void *ctx)
1058 struct bpf_dynptr ptr;
1063 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &data.ptr);
1064 /* this should fail */
1065 bpf_dynptr_read(data.buf, sizeof(data.buf), &data.ptr, 0, 0);
1070 /* bpf_dynptr_slice()s are read-only and cannot be written to */
1072 __failure __msg("R0 cannot write into rdonly_mem")
1073 int skb_invalid_slice_write(struct __sk_buff *skb)
1075 struct bpf_dynptr ptr;
1077 char buffer[sizeof(*hdr)] = {};
1079 bpf_dynptr_from_skb(skb, 0, &ptr);
1081 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1085 /* this should fail */
1091 /* The read-only data slice is invalidated whenever a helper changes packet data */
1093 __failure __msg("invalid mem access 'scalar'")
1094 int skb_invalid_data_slice1(struct __sk_buff *skb)
1096 struct bpf_dynptr ptr;
1098 char buffer[sizeof(*hdr)] = {};
1100 bpf_dynptr_from_skb(skb, 0, &ptr);
1102 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1108 if (bpf_skb_pull_data(skb, skb->len))
1111 /* this should fail */
1117 /* The read-write data slice is invalidated whenever a helper changes packet data */
1119 __failure __msg("invalid mem access 'scalar'")
1120 int skb_invalid_data_slice2(struct __sk_buff *skb)
1122 struct bpf_dynptr ptr;
1124 char buffer[sizeof(*hdr)] = {};
1126 bpf_dynptr_from_skb(skb, 0, &ptr);
1128 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1134 if (bpf_skb_pull_data(skb, skb->len))
1137 /* this should fail */
1143 /* The read-only data slice is invalidated whenever bpf_dynptr_write() is called */
1145 __failure __msg("invalid mem access 'scalar'")
1146 int skb_invalid_data_slice3(struct __sk_buff *skb)
1148 char write_data[64] = "hello there, world!!";
1149 struct bpf_dynptr ptr;
1151 char buffer[sizeof(*hdr)] = {};
1153 bpf_dynptr_from_skb(skb, 0, &ptr);
1155 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1161 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
1163 /* this should fail */
1169 /* The read-write data slice is invalidated whenever bpf_dynptr_write() is called */
1171 __failure __msg("invalid mem access 'scalar'")
1172 int skb_invalid_data_slice4(struct __sk_buff *skb)
1174 char write_data[64] = "hello there, world!!";
1175 struct bpf_dynptr ptr;
1177 char buffer[sizeof(*hdr)] = {};
1179 bpf_dynptr_from_skb(skb, 0, &ptr);
1180 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1186 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0);
1188 /* this should fail */
1194 /* The read-only data slice is invalidated whenever a helper changes packet data */
1196 __failure __msg("invalid mem access 'scalar'")
1197 int xdp_invalid_data_slice1(struct xdp_md *xdp)
1199 struct bpf_dynptr ptr;
1201 char buffer[sizeof(*hdr)] = {};
1203 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1204 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer));
1210 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1213 /* this should fail */
1219 /* The read-write data slice is invalidated whenever a helper changes packet data */
1221 __failure __msg("invalid mem access 'scalar'")
1222 int xdp_invalid_data_slice2(struct xdp_md *xdp)
1224 struct bpf_dynptr ptr;
1226 char buffer[sizeof(*hdr)] = {};
1228 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1229 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1235 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1238 /* this should fail */
1244 /* Only supported prog type can create skb-type dynptrs */
1246 __failure __msg("calling kernel function bpf_dynptr_from_skb is not allowed")
1247 int skb_invalid_ctx(void *ctx)
1249 struct bpf_dynptr ptr;
1251 /* this should fail */
1252 bpf_dynptr_from_skb(ctx, 0, &ptr);
1257 /* Reject writes to dynptr slot for uninit arg */
1259 __failure __msg("potential write to dynptr at off=-16")
1260 int uninit_write_into_slot(void *ctx)
1264 struct bpf_dynptr ptr;
1267 bpf_ringbuf_reserve_dynptr(&ringbuf, 80, 0, &data.ptr);
1268 /* this should fail */
1269 bpf_get_current_comm(data.buf, 80);
1274 /* Only supported prog type can create xdp-type dynptrs */
1276 __failure __msg("calling kernel function bpf_dynptr_from_xdp is not allowed")
1277 int xdp_invalid_ctx(void *ctx)
1279 struct bpf_dynptr ptr;
1281 /* this should fail */
1282 bpf_dynptr_from_xdp(ctx, 0, &ptr);
1287 __u32 hdr_size = sizeof(struct ethhdr);
1288 /* Can't pass in variable-sized len to bpf_dynptr_slice */
1290 __failure __msg("unbounded memory access")
1291 int dynptr_slice_var_len1(struct __sk_buff *skb)
1293 struct bpf_dynptr ptr;
1295 char buffer[sizeof(*hdr)] = {};
1297 bpf_dynptr_from_skb(skb, 0, &ptr);
1299 /* this should fail */
1300 hdr = bpf_dynptr_slice(&ptr, 0, buffer, hdr_size);
1307 /* Can't pass in variable-sized len to bpf_dynptr_slice */
1309 __failure __msg("must be a known constant")
1310 int dynptr_slice_var_len2(struct __sk_buff *skb)
1312 char buffer[sizeof(struct ethhdr)] = {};
1313 struct bpf_dynptr ptr;
1316 bpf_dynptr_from_skb(skb, 0, &ptr);
1318 if (hdr_size <= sizeof(buffer)) {
1319 /* this should fail */
1320 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, hdr_size);
1329 static int callback(__u32 index, void *data)
1331 *(__u32 *)data = 123;
1336 /* If the dynptr is written into in a callback function, its data
1337 * slices should be invalidated as well.
1340 __failure __msg("invalid mem access 'scalar'")
1341 int invalid_data_slices(void *ctx)
1343 struct bpf_dynptr ptr;
1346 if (get_map_val_dynptr(&ptr))
1349 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32));
1353 bpf_loop(10, callback, &ptr, 0);
1355 /* this should fail */
1361 /* Program types that don't allow writes to packet data should fail if
1362 * bpf_dynptr_slice_rdwr is called
1364 SEC("cgroup_skb/ingress")
1365 __failure __msg("the prog does not allow writes to packet data")
1366 int invalid_slice_rdwr_rdonly(struct __sk_buff *skb)
1368 char buffer[sizeof(struct ethhdr)] = {};
1369 struct bpf_dynptr ptr;
1372 bpf_dynptr_from_skb(skb, 0, &ptr);
1374 /* this should fail since cgroup_skb doesn't allow
1375 * changing packet data
1377 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer));
1383 /* bpf_dynptr_adjust can only be called on initialized dynptrs */
1385 __failure __msg("Expected an initialized dynptr as arg #1")
1386 int dynptr_adjust_invalid(void *ctx)
1388 struct bpf_dynptr ptr;
1390 /* this should fail */
1391 bpf_dynptr_adjust(&ptr, 1, 2);
1396 /* bpf_dynptr_is_null can only be called on initialized dynptrs */
1398 __failure __msg("Expected an initialized dynptr as arg #1")
1399 int dynptr_is_null_invalid(void *ctx)
1401 struct bpf_dynptr ptr;
1403 /* this should fail */
1404 bpf_dynptr_is_null(&ptr);
1409 /* bpf_dynptr_is_rdonly can only be called on initialized dynptrs */
1411 __failure __msg("Expected an initialized dynptr as arg #1")
1412 int dynptr_is_rdonly_invalid(void *ctx)
1414 struct bpf_dynptr ptr;
1416 /* this should fail */
1417 bpf_dynptr_is_rdonly(&ptr);
1422 /* bpf_dynptr_size can only be called on initialized dynptrs */
1424 __failure __msg("Expected an initialized dynptr as arg #1")
1425 int dynptr_size_invalid(void *ctx)
1427 struct bpf_dynptr ptr;
1429 /* this should fail */
1430 bpf_dynptr_size(&ptr);
1435 /* Only initialized dynptrs can be cloned */
1437 __failure __msg("Expected an initialized dynptr as arg #1")
1438 int clone_invalid1(void *ctx)
1440 struct bpf_dynptr ptr1;
1441 struct bpf_dynptr ptr2;
1443 /* this should fail */
1444 bpf_dynptr_clone(&ptr1, &ptr2);
1449 /* Can't overwrite an existing dynptr when cloning */
1451 __failure __msg("cannot overwrite referenced dynptr")
1452 int clone_invalid2(struct xdp_md *xdp)
1454 struct bpf_dynptr ptr1;
1455 struct bpf_dynptr clone;
1457 bpf_dynptr_from_xdp(xdp, 0, &ptr1);
1459 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &clone);
1461 /* this should fail */
1462 bpf_dynptr_clone(&ptr1, &clone);
1464 bpf_ringbuf_submit_dynptr(&clone, 0);
1469 /* Invalidating a dynptr should invalidate its clones */
1471 __failure __msg("Expected an initialized dynptr as arg #3")
1472 int clone_invalidate1(void *ctx)
1474 struct bpf_dynptr clone;
1475 struct bpf_dynptr ptr;
1478 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1480 bpf_dynptr_clone(&ptr, &clone);
1482 bpf_ringbuf_submit_dynptr(&ptr, 0);
1484 /* this should fail */
1485 bpf_dynptr_read(read_data, sizeof(read_data), &clone, 0, 0);
1490 /* Invalidating a dynptr should invalidate its parent */
1492 __failure __msg("Expected an initialized dynptr as arg #3")
1493 int clone_invalidate2(void *ctx)
1495 struct bpf_dynptr ptr;
1496 struct bpf_dynptr clone;
1499 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1501 bpf_dynptr_clone(&ptr, &clone);
1503 bpf_ringbuf_submit_dynptr(&clone, 0);
1505 /* this should fail */
1506 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
1511 /* Invalidating a dynptr should invalidate its siblings */
1513 __failure __msg("Expected an initialized dynptr as arg #3")
1514 int clone_invalidate3(void *ctx)
1516 struct bpf_dynptr ptr;
1517 struct bpf_dynptr clone1;
1518 struct bpf_dynptr clone2;
1521 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1523 bpf_dynptr_clone(&ptr, &clone1);
1525 bpf_dynptr_clone(&ptr, &clone2);
1527 bpf_ringbuf_submit_dynptr(&clone2, 0);
1529 /* this should fail */
1530 bpf_dynptr_read(read_data, sizeof(read_data), &clone1, 0, 0);
1535 /* Invalidating a dynptr should invalidate any data slices
1539 __failure __msg("invalid mem access 'scalar'")
1540 int clone_invalidate4(void *ctx)
1542 struct bpf_dynptr ptr;
1543 struct bpf_dynptr clone;
1546 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1548 bpf_dynptr_clone(&ptr, &clone);
1549 data = bpf_dynptr_data(&clone, 0, sizeof(val));
1553 bpf_ringbuf_submit_dynptr(&ptr, 0);
1555 /* this should fail */
1561 /* Invalidating a dynptr should invalidate any data slices
1565 __failure __msg("invalid mem access 'scalar'")
1566 int clone_invalidate5(void *ctx)
1568 struct bpf_dynptr ptr;
1569 struct bpf_dynptr clone;
1572 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1573 data = bpf_dynptr_data(&ptr, 0, sizeof(val));
1577 bpf_dynptr_clone(&ptr, &clone);
1579 bpf_ringbuf_submit_dynptr(&clone, 0);
1581 /* this should fail */
1587 /* Invalidating a dynptr should invalidate any data slices
1591 __failure __msg("invalid mem access 'scalar'")
1592 int clone_invalidate6(void *ctx)
1594 struct bpf_dynptr ptr;
1595 struct bpf_dynptr clone1;
1596 struct bpf_dynptr clone2;
1599 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
1601 bpf_dynptr_clone(&ptr, &clone1);
1603 bpf_dynptr_clone(&ptr, &clone2);
1605 data = bpf_dynptr_data(&clone1, 0, sizeof(val));
1609 bpf_ringbuf_submit_dynptr(&clone2, 0);
1611 /* this should fail */
1617 /* A skb clone's data slices should be invalid anytime packet data changes */
1619 __failure __msg("invalid mem access 'scalar'")
1620 int clone_skb_packet_data(struct __sk_buff *skb)
1622 char buffer[sizeof(__u32)] = {};
1623 struct bpf_dynptr clone;
1624 struct bpf_dynptr ptr;
1627 bpf_dynptr_from_skb(skb, 0, &ptr);
1629 bpf_dynptr_clone(&ptr, &clone);
1630 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer));
1634 if (bpf_skb_pull_data(skb, skb->len))
1637 /* this should fail */
1643 /* A xdp clone's data slices should be invalid anytime packet data changes */
1645 __failure __msg("invalid mem access 'scalar'")
1646 int clone_xdp_packet_data(struct xdp_md *xdp)
1648 char buffer[sizeof(__u32)] = {};
1649 struct bpf_dynptr clone;
1650 struct bpf_dynptr ptr;
1654 bpf_dynptr_from_xdp(xdp, 0, &ptr);
1656 bpf_dynptr_clone(&ptr, &clone);
1657 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer));
1661 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr)))
1664 /* this should fail */
1670 /* Buffers that are provided must be sufficiently long */
1671 SEC("?cgroup_skb/egress")
1672 __failure __msg("memory, len pair leads to invalid memory access")
1673 int test_dynptr_skb_small_buff(struct __sk_buff *skb)
1675 struct bpf_dynptr ptr;
1676 char buffer[8] = {};
1679 if (bpf_dynptr_from_skb(skb, 0, &ptr)) {
1684 /* This may return NULL. SKB may require a buffer */
1685 data = bpf_dynptr_slice(&ptr, 0, buffer, 9);