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