1 // SPDX-License-Identifier: GPL-2.0
2 #include <vmlinux.h>
3 #include <bpf/bpf_tracing.h>
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_core_read.h>
6
7 struct map_value {
8 char buf[8];
9 struct prog_test_ref_kfunc __kptr *unref_ptr;
10 struct prog_test_ref_kfunc __kptr_ref *ref_ptr;
11 struct prog_test_member __kptr_ref *ref_memb_ptr;
12 };
13
14 struct array_map {
15 __uint(type, BPF_MAP_TYPE_ARRAY);
16 __type(key, int);
17 __type(value, struct map_value);
18 __uint(max_entries, 1);
19 } array_map SEC(".maps");
20
21 extern struct prog_test_ref_kfunc *bpf_kfunc_call_test_acquire(unsigned long *sp) __ksym;
22 extern struct prog_test_ref_kfunc *
23 bpf_kfunc_call_test_kptr_get(struct prog_test_ref_kfunc **p, int a, int b) __ksym;
24
25 SEC("?tc")
size_not_bpf_dw(struct __sk_buff * ctx)26 int size_not_bpf_dw(struct __sk_buff *ctx)
27 {
28 struct map_value *v;
29 int key = 0;
30
31 v = bpf_map_lookup_elem(&array_map, &key);
32 if (!v)
33 return 0;
34
35 *(u32 *)&v->unref_ptr = 0;
36 return 0;
37 }
38
39 SEC("?tc")
non_const_var_off(struct __sk_buff * ctx)40 int non_const_var_off(struct __sk_buff *ctx)
41 {
42 struct map_value *v;
43 int key = 0, id;
44
45 v = bpf_map_lookup_elem(&array_map, &key);
46 if (!v)
47 return 0;
48
49 id = ctx->protocol;
50 if (id < 4 || id > 12)
51 return 0;
52 *(u64 *)((void *)v + id) = 0;
53
54 return 0;
55 }
56
57 SEC("?tc")
non_const_var_off_kptr_xchg(struct __sk_buff * ctx)58 int non_const_var_off_kptr_xchg(struct __sk_buff *ctx)
59 {
60 struct map_value *v;
61 int key = 0, id;
62
63 v = bpf_map_lookup_elem(&array_map, &key);
64 if (!v)
65 return 0;
66
67 id = ctx->protocol;
68 if (id < 4 || id > 12)
69 return 0;
70 bpf_kptr_xchg((void *)v + id, NULL);
71
72 return 0;
73 }
74
75 SEC("?tc")
misaligned_access_write(struct __sk_buff * ctx)76 int misaligned_access_write(struct __sk_buff *ctx)
77 {
78 struct map_value *v;
79 int key = 0;
80
81 v = bpf_map_lookup_elem(&array_map, &key);
82 if (!v)
83 return 0;
84
85 *(void **)((void *)v + 7) = NULL;
86
87 return 0;
88 }
89
90 SEC("?tc")
misaligned_access_read(struct __sk_buff * ctx)91 int misaligned_access_read(struct __sk_buff *ctx)
92 {
93 struct map_value *v;
94 int key = 0;
95
96 v = bpf_map_lookup_elem(&array_map, &key);
97 if (!v)
98 return 0;
99
100 return *(u64 *)((void *)v + 1);
101 }
102
103 SEC("?tc")
reject_var_off_store(struct __sk_buff * ctx)104 int reject_var_off_store(struct __sk_buff *ctx)
105 {
106 struct prog_test_ref_kfunc *unref_ptr;
107 struct map_value *v;
108 int key = 0, id;
109
110 v = bpf_map_lookup_elem(&array_map, &key);
111 if (!v)
112 return 0;
113
114 unref_ptr = v->unref_ptr;
115 if (!unref_ptr)
116 return 0;
117 id = ctx->protocol;
118 if (id < 4 || id > 12)
119 return 0;
120 unref_ptr += id;
121 v->unref_ptr = unref_ptr;
122
123 return 0;
124 }
125
126 SEC("?tc")
reject_bad_type_match(struct __sk_buff * ctx)127 int reject_bad_type_match(struct __sk_buff *ctx)
128 {
129 struct prog_test_ref_kfunc *unref_ptr;
130 struct map_value *v;
131 int key = 0;
132
133 v = bpf_map_lookup_elem(&array_map, &key);
134 if (!v)
135 return 0;
136
137 unref_ptr = v->unref_ptr;
138 if (!unref_ptr)
139 return 0;
140 unref_ptr = (void *)unref_ptr + 4;
141 v->unref_ptr = unref_ptr;
142
143 return 0;
144 }
145
146 SEC("?tc")
marked_as_untrusted_or_null(struct __sk_buff * ctx)147 int marked_as_untrusted_or_null(struct __sk_buff *ctx)
148 {
149 struct map_value *v;
150 int key = 0;
151
152 v = bpf_map_lookup_elem(&array_map, &key);
153 if (!v)
154 return 0;
155
156 bpf_this_cpu_ptr(v->unref_ptr);
157 return 0;
158 }
159
160 SEC("?tc")
correct_btf_id_check_size(struct __sk_buff * ctx)161 int correct_btf_id_check_size(struct __sk_buff *ctx)
162 {
163 struct prog_test_ref_kfunc *p;
164 struct map_value *v;
165 int key = 0;
166
167 v = bpf_map_lookup_elem(&array_map, &key);
168 if (!v)
169 return 0;
170
171 p = v->unref_ptr;
172 if (!p)
173 return 0;
174 return *(int *)((void *)p + bpf_core_type_size(struct prog_test_ref_kfunc));
175 }
176
177 SEC("?tc")
inherit_untrusted_on_walk(struct __sk_buff * ctx)178 int inherit_untrusted_on_walk(struct __sk_buff *ctx)
179 {
180 struct prog_test_ref_kfunc *unref_ptr;
181 struct map_value *v;
182 int key = 0;
183
184 v = bpf_map_lookup_elem(&array_map, &key);
185 if (!v)
186 return 0;
187
188 unref_ptr = v->unref_ptr;
189 if (!unref_ptr)
190 return 0;
191 unref_ptr = unref_ptr->next;
192 bpf_this_cpu_ptr(unref_ptr);
193 return 0;
194 }
195
196 SEC("?tc")
reject_kptr_xchg_on_unref(struct __sk_buff * ctx)197 int reject_kptr_xchg_on_unref(struct __sk_buff *ctx)
198 {
199 struct map_value *v;
200 int key = 0;
201
202 v = bpf_map_lookup_elem(&array_map, &key);
203 if (!v)
204 return 0;
205
206 bpf_kptr_xchg(&v->unref_ptr, NULL);
207 return 0;
208 }
209
210 SEC("?tc")
reject_kptr_get_no_map_val(struct __sk_buff * ctx)211 int reject_kptr_get_no_map_val(struct __sk_buff *ctx)
212 {
213 bpf_kfunc_call_test_kptr_get((void *)&ctx, 0, 0);
214 return 0;
215 }
216
217 SEC("?tc")
reject_kptr_get_no_null_map_val(struct __sk_buff * ctx)218 int reject_kptr_get_no_null_map_val(struct __sk_buff *ctx)
219 {
220 bpf_kfunc_call_test_kptr_get(bpf_map_lookup_elem(&array_map, &(int){0}), 0, 0);
221 return 0;
222 }
223
224 SEC("?tc")
reject_kptr_get_no_kptr(struct __sk_buff * ctx)225 int reject_kptr_get_no_kptr(struct __sk_buff *ctx)
226 {
227 struct map_value *v;
228 int key = 0;
229
230 v = bpf_map_lookup_elem(&array_map, &key);
231 if (!v)
232 return 0;
233
234 bpf_kfunc_call_test_kptr_get((void *)v, 0, 0);
235 return 0;
236 }
237
238 SEC("?tc")
reject_kptr_get_on_unref(struct __sk_buff * ctx)239 int reject_kptr_get_on_unref(struct __sk_buff *ctx)
240 {
241 struct map_value *v;
242 int key = 0;
243
244 v = bpf_map_lookup_elem(&array_map, &key);
245 if (!v)
246 return 0;
247
248 bpf_kfunc_call_test_kptr_get(&v->unref_ptr, 0, 0);
249 return 0;
250 }
251
252 SEC("?tc")
reject_kptr_get_bad_type_match(struct __sk_buff * ctx)253 int reject_kptr_get_bad_type_match(struct __sk_buff *ctx)
254 {
255 struct map_value *v;
256 int key = 0;
257
258 v = bpf_map_lookup_elem(&array_map, &key);
259 if (!v)
260 return 0;
261
262 bpf_kfunc_call_test_kptr_get((void *)&v->ref_memb_ptr, 0, 0);
263 return 0;
264 }
265
266 SEC("?tc")
mark_ref_as_untrusted_or_null(struct __sk_buff * ctx)267 int mark_ref_as_untrusted_or_null(struct __sk_buff *ctx)
268 {
269 struct map_value *v;
270 int key = 0;
271
272 v = bpf_map_lookup_elem(&array_map, &key);
273 if (!v)
274 return 0;
275
276 bpf_this_cpu_ptr(v->ref_ptr);
277 return 0;
278 }
279
280 SEC("?tc")
reject_untrusted_store_to_ref(struct __sk_buff * ctx)281 int reject_untrusted_store_to_ref(struct __sk_buff *ctx)
282 {
283 struct prog_test_ref_kfunc *p;
284 struct map_value *v;
285 int key = 0;
286
287 v = bpf_map_lookup_elem(&array_map, &key);
288 if (!v)
289 return 0;
290
291 p = v->ref_ptr;
292 if (!p)
293 return 0;
294 /* Checkmate, clang */
295 *(struct prog_test_ref_kfunc * volatile *)&v->ref_ptr = p;
296 return 0;
297 }
298
299 SEC("?tc")
reject_untrusted_xchg(struct __sk_buff * ctx)300 int reject_untrusted_xchg(struct __sk_buff *ctx)
301 {
302 struct prog_test_ref_kfunc *p;
303 struct map_value *v;
304 int key = 0;
305
306 v = bpf_map_lookup_elem(&array_map, &key);
307 if (!v)
308 return 0;
309
310 p = v->ref_ptr;
311 if (!p)
312 return 0;
313 bpf_kptr_xchg(&v->ref_ptr, p);
314 return 0;
315 }
316
317 SEC("?tc")
reject_bad_type_xchg(struct __sk_buff * ctx)318 int reject_bad_type_xchg(struct __sk_buff *ctx)
319 {
320 struct prog_test_ref_kfunc *ref_ptr;
321 struct map_value *v;
322 int key = 0;
323
324 v = bpf_map_lookup_elem(&array_map, &key);
325 if (!v)
326 return 0;
327
328 ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});
329 if (!ref_ptr)
330 return 0;
331 bpf_kptr_xchg(&v->ref_memb_ptr, ref_ptr);
332 return 0;
333 }
334
335 SEC("?tc")
reject_member_of_ref_xchg(struct __sk_buff * ctx)336 int reject_member_of_ref_xchg(struct __sk_buff *ctx)
337 {
338 struct prog_test_ref_kfunc *ref_ptr;
339 struct map_value *v;
340 int key = 0;
341
342 v = bpf_map_lookup_elem(&array_map, &key);
343 if (!v)
344 return 0;
345
346 ref_ptr = bpf_kfunc_call_test_acquire(&(unsigned long){0});
347 if (!ref_ptr)
348 return 0;
349 bpf_kptr_xchg(&v->ref_memb_ptr, &ref_ptr->memb);
350 return 0;
351 }
352
353 SEC("?syscall")
reject_indirect_helper_access(struct __sk_buff * ctx)354 int reject_indirect_helper_access(struct __sk_buff *ctx)
355 {
356 struct map_value *v;
357 int key = 0;
358
359 v = bpf_map_lookup_elem(&array_map, &key);
360 if (!v)
361 return 0;
362
363 bpf_get_current_comm(v, sizeof(v->buf) + 1);
364 return 0;
365 }
366
367 __noinline
write_func(int * p)368 int write_func(int *p)
369 {
370 return p ? *p = 42 : 0;
371 }
372
373 SEC("?tc")
reject_indirect_global_func_access(struct __sk_buff * ctx)374 int reject_indirect_global_func_access(struct __sk_buff *ctx)
375 {
376 struct map_value *v;
377 int key = 0;
378
379 v = bpf_map_lookup_elem(&array_map, &key);
380 if (!v)
381 return 0;
382
383 return write_func((void *)v + 5);
384 }
385
386 SEC("?tc")
kptr_xchg_ref_state(struct __sk_buff * ctx)387 int kptr_xchg_ref_state(struct __sk_buff *ctx)
388 {
389 struct prog_test_ref_kfunc *p;
390 struct map_value *v;
391 int key = 0;
392
393 v = bpf_map_lookup_elem(&array_map, &key);
394 if (!v)
395 return 0;
396
397 p = bpf_kfunc_call_test_acquire(&(unsigned long){0});
398 if (!p)
399 return 0;
400 bpf_kptr_xchg(&v->ref_ptr, p);
401 return 0;
402 }
403
404 SEC("?tc")
kptr_get_ref_state(struct __sk_buff * ctx)405 int kptr_get_ref_state(struct __sk_buff *ctx)
406 {
407 struct map_value *v;
408 int key = 0;
409
410 v = bpf_map_lookup_elem(&array_map, &key);
411 if (!v)
412 return 0;
413
414 bpf_kfunc_call_test_kptr_get(&v->ref_ptr, 0, 0);
415 return 0;
416 }
417
418 char _license[] SEC("license") = "GPL";
419