1 #include "bpf_experimental.h" 2 #include "bpf_misc.h" 3 4 struct val_t { 5 long b, c, d; 6 }; 7 8 struct val2_t { 9 long b; 10 }; 11 12 struct val_with_ptr_t { 13 char *p; 14 }; 15 16 struct val_with_rb_root_t { 17 struct bpf_spin_lock lock; 18 }; 19 20 struct elem { 21 long sum; 22 struct val_t __percpu_kptr *pc; 23 }; 24 25 struct { 26 __uint(type, BPF_MAP_TYPE_ARRAY); 27 __uint(max_entries, 1); 28 __type(key, int); 29 __type(value, struct elem); 30 } array SEC(".maps"); 31 32 long ret; 33 34 SEC("?fentry/bpf_fentry_test1") 35 __failure __msg("store to referenced kptr disallowed") 36 int BPF_PROG(test_array_map_1) 37 { 38 struct val_t __percpu_kptr *p; 39 struct elem *e; 40 int index = 0; 41 42 e = bpf_map_lookup_elem(&array, &index); 43 if (!e) 44 return 0; 45 46 p = bpf_percpu_obj_new(struct val_t); 47 if (!p) 48 return 0; 49 50 p = bpf_kptr_xchg(&e->pc, p); 51 if (p) 52 bpf_percpu_obj_drop(p); 53 54 e->pc = (struct val_t __percpu_kptr *)ret; 55 return 0; 56 } 57 58 SEC("?fentry/bpf_fentry_test1") 59 __failure __msg("invalid kptr access, R2 type=percpu_ptr_val2_t expected=ptr_val_t") 60 int BPF_PROG(test_array_map_2) 61 { 62 struct val2_t __percpu_kptr *p2; 63 struct val_t __percpu_kptr *p; 64 struct elem *e; 65 int index = 0; 66 67 e = bpf_map_lookup_elem(&array, &index); 68 if (!e) 69 return 0; 70 71 p2 = bpf_percpu_obj_new(struct val2_t); 72 if (!p2) 73 return 0; 74 75 p = bpf_kptr_xchg(&e->pc, p2); 76 if (p) 77 bpf_percpu_obj_drop(p); 78 79 return 0; 80 } 81 82 SEC("?fentry.s/bpf_fentry_test1") 83 __failure __msg("R1 type=scalar expected=percpu_ptr_, percpu_rcu_ptr_, percpu_trusted_ptr_") 84 int BPF_PROG(test_array_map_3) 85 { 86 struct val_t __percpu_kptr *p, *p1; 87 struct val_t *v; 88 struct elem *e; 89 int index = 0; 90 91 e = bpf_map_lookup_elem(&array, &index); 92 if (!e) 93 return 0; 94 95 p = bpf_percpu_obj_new(struct val_t); 96 if (!p) 97 return 0; 98 99 p1 = bpf_kptr_xchg(&e->pc, p); 100 if (p1) 101 bpf_percpu_obj_drop(p1); 102 103 v = bpf_this_cpu_ptr(p); 104 ret = v->b; 105 return 0; 106 } 107 108 SEC("?fentry.s/bpf_fentry_test1") 109 __failure __msg("arg#0 expected for bpf_percpu_obj_drop_impl()") 110 int BPF_PROG(test_array_map_4) 111 { 112 struct val_t __percpu_kptr *p; 113 114 p = bpf_percpu_obj_new(struct val_t); 115 if (!p) 116 return 0; 117 118 bpf_obj_drop(p); 119 return 0; 120 } 121 122 SEC("?fentry.s/bpf_fentry_test1") 123 __failure __msg("arg#0 expected for bpf_obj_drop_impl()") 124 int BPF_PROG(test_array_map_5) 125 { 126 struct val_t *p; 127 128 p = bpf_obj_new(struct val_t); 129 if (!p) 130 return 0; 131 132 bpf_percpu_obj_drop(p); 133 return 0; 134 } 135 136 SEC("?fentry.s/bpf_fentry_test1") 137 __failure __msg("bpf_percpu_obj_new type ID argument must be of a struct of scalars") 138 int BPF_PROG(test_array_map_6) 139 { 140 struct val_with_ptr_t __percpu_kptr *p; 141 142 p = bpf_percpu_obj_new(struct val_with_ptr_t); 143 if (!p) 144 return 0; 145 146 bpf_percpu_obj_drop(p); 147 return 0; 148 } 149 150 SEC("?fentry.s/bpf_fentry_test1") 151 __failure __msg("bpf_percpu_obj_new type ID argument must not contain special fields") 152 int BPF_PROG(test_array_map_7) 153 { 154 struct val_with_rb_root_t __percpu_kptr *p; 155 156 p = bpf_percpu_obj_new(struct val_with_rb_root_t); 157 if (!p) 158 return 0; 159 160 bpf_percpu_obj_drop(p); 161 return 0; 162 } 163 164 char _license[] SEC("license") = "GPL"; 165