Merge tag 'lsm-pr-20220801' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm
[platform/kernel/linux-starfive.git] / tools / testing / selftests / bpf / progs / dynptr_fail.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2022 Facebook */
3
4 #include <errno.h>
5 #include <string.h>
6 #include <linux/bpf.h>
7 #include <bpf/bpf_helpers.h>
8 #include "bpf_misc.h"
9
10 char _license[] SEC("license") = "GPL";
11
12 struct test_info {
13         int x;
14         struct bpf_dynptr ptr;
15 };
16
17 struct {
18         __uint(type, BPF_MAP_TYPE_ARRAY);
19         __uint(max_entries, 1);
20         __type(key, __u32);
21         __type(value, struct bpf_dynptr);
22 } array_map1 SEC(".maps");
23
24 struct {
25         __uint(type, BPF_MAP_TYPE_ARRAY);
26         __uint(max_entries, 1);
27         __type(key, __u32);
28         __type(value, struct test_info);
29 } array_map2 SEC(".maps");
30
31 struct {
32         __uint(type, BPF_MAP_TYPE_ARRAY);
33         __uint(max_entries, 1);
34         __type(key, __u32);
35         __type(value, __u32);
36 } array_map3 SEC(".maps");
37
38 struct sample {
39         int pid;
40         long value;
41         char comm[16];
42 };
43
44 struct {
45         __uint(type, BPF_MAP_TYPE_RINGBUF);
46 } ringbuf SEC(".maps");
47
48 int err, val;
49
50 static int get_map_val_dynptr(struct bpf_dynptr *ptr)
51 {
52         __u32 key = 0, *map_val;
53
54         bpf_map_update_elem(&array_map3, &key, &val, 0);
55
56         map_val = bpf_map_lookup_elem(&array_map3, &key);
57         if (!map_val)
58                 return -ENOENT;
59
60         bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr);
61
62         return 0;
63 }
64
65 /* Every bpf_ringbuf_reserve_dynptr call must have a corresponding
66  * bpf_ringbuf_submit/discard_dynptr call
67  */
68 SEC("?raw_tp/sys_nanosleep")
69 int ringbuf_missing_release1(void *ctx)
70 {
71         struct bpf_dynptr ptr;
72
73         bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
74
75         /* missing a call to bpf_ringbuf_discard/submit_dynptr */
76
77         return 0;
78 }
79
80 SEC("?raw_tp/sys_nanosleep")
81 int ringbuf_missing_release2(void *ctx)
82 {
83         struct bpf_dynptr ptr1, ptr2;
84         struct sample *sample;
85
86         bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1);
87         bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
88
89         sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample));
90         if (!sample) {
91                 bpf_ringbuf_discard_dynptr(&ptr1, 0);
92                 bpf_ringbuf_discard_dynptr(&ptr2, 0);
93                 return 0;
94         }
95
96         bpf_ringbuf_submit_dynptr(&ptr1, 0);
97
98         /* missing a call to bpf_ringbuf_discard/submit_dynptr on ptr2 */
99
100         return 0;
101 }
102
103 static int missing_release_callback_fn(__u32 index, void *data)
104 {
105         struct bpf_dynptr ptr;
106
107         bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
108
109         /* missing a call to bpf_ringbuf_discard/submit_dynptr */
110
111         return 0;
112 }
113
114 /* Any dynptr initialized within a callback must have bpf_dynptr_put called */
115 SEC("?raw_tp/sys_nanosleep")
116 int ringbuf_missing_release_callback(void *ctx)
117 {
118         bpf_loop(10, missing_release_callback_fn, NULL, 0);
119         return 0;
120 }
121
122 /* Can't call bpf_ringbuf_submit/discard_dynptr on a non-initialized dynptr */
123 SEC("?raw_tp/sys_nanosleep")
124 int ringbuf_release_uninit_dynptr(void *ctx)
125 {
126         struct bpf_dynptr ptr;
127
128         /* this should fail */
129         bpf_ringbuf_submit_dynptr(&ptr, 0);
130
131         return 0;
132 }
133
134 /* A dynptr can't be used after it has been invalidated */
135 SEC("?raw_tp/sys_nanosleep")
136 int use_after_invalid(void *ctx)
137 {
138         struct bpf_dynptr ptr;
139         char read_data[64];
140
141         bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr);
142
143         bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
144
145         bpf_ringbuf_submit_dynptr(&ptr, 0);
146
147         /* this should fail */
148         bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
149
150         return 0;
151 }
152
153 /* Can't call non-dynptr ringbuf APIs on a dynptr ringbuf sample */
154 SEC("?raw_tp/sys_nanosleep")
155 int ringbuf_invalid_api(void *ctx)
156 {
157         struct bpf_dynptr ptr;
158         struct sample *sample;
159
160         bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
161         sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
162         if (!sample)
163                 goto done;
164
165         sample->pid = 123;
166
167         /* invalid API use. need to use dynptr API to submit/discard */
168         bpf_ringbuf_submit(sample, 0);
169
170 done:
171         bpf_ringbuf_discard_dynptr(&ptr, 0);
172         return 0;
173 }
174
175 /* Can't add a dynptr to a map */
176 SEC("?raw_tp/sys_nanosleep")
177 int add_dynptr_to_map1(void *ctx)
178 {
179         struct bpf_dynptr ptr;
180         int key = 0;
181
182         bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
183
184         /* this should fail */
185         bpf_map_update_elem(&array_map1, &key, &ptr, 0);
186
187         bpf_ringbuf_submit_dynptr(&ptr, 0);
188
189         return 0;
190 }
191
192 /* Can't add a struct with an embedded dynptr to a map */
193 SEC("?raw_tp/sys_nanosleep")
194 int add_dynptr_to_map2(void *ctx)
195 {
196         struct test_info x;
197         int key = 0;
198
199         bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr);
200
201         /* this should fail */
202         bpf_map_update_elem(&array_map2, &key, &x, 0);
203
204         bpf_ringbuf_submit_dynptr(&x.ptr, 0);
205
206         return 0;
207 }
208
209 /* A data slice can't be accessed out of bounds */
210 SEC("?raw_tp/sys_nanosleep")
211 int data_slice_out_of_bounds_ringbuf(void *ctx)
212 {
213         struct bpf_dynptr ptr;
214         void *data;
215
216         bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
217
218         data  = bpf_dynptr_data(&ptr, 0, 8);
219         if (!data)
220                 goto done;
221
222         /* can't index out of bounds of the data slice */
223         val = *((char *)data + 8);
224
225 done:
226         bpf_ringbuf_submit_dynptr(&ptr, 0);
227         return 0;
228 }
229
230 SEC("?raw_tp/sys_nanosleep")
231 int data_slice_out_of_bounds_map_value(void *ctx)
232 {
233         __u32 key = 0, map_val;
234         struct bpf_dynptr ptr;
235         void *data;
236
237         get_map_val_dynptr(&ptr);
238
239         data  = bpf_dynptr_data(&ptr, 0, sizeof(map_val));
240         if (!data)
241                 return 0;
242
243         /* can't index out of bounds of the data slice */
244         val = *((char *)data + (sizeof(map_val) + 1));
245
246         return 0;
247 }
248
249 /* A data slice can't be used after it has been released */
250 SEC("?raw_tp/sys_nanosleep")
251 int data_slice_use_after_release(void *ctx)
252 {
253         struct bpf_dynptr ptr;
254         struct sample *sample;
255
256         bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
257         sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
258         if (!sample)
259                 goto done;
260
261         sample->pid = 123;
262
263         bpf_ringbuf_submit_dynptr(&ptr, 0);
264
265         /* this should fail */
266         val = sample->pid;
267
268         return 0;
269
270 done:
271         bpf_ringbuf_discard_dynptr(&ptr, 0);
272         return 0;
273 }
274
275 /* A data slice must be first checked for NULL */
276 SEC("?raw_tp/sys_nanosleep")
277 int data_slice_missing_null_check1(void *ctx)
278 {
279         struct bpf_dynptr ptr;
280         void *data;
281
282         bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
283
284         data  = bpf_dynptr_data(&ptr, 0, 8);
285
286         /* missing if (!data) check */
287
288         /* this should fail */
289         *(__u8 *)data = 3;
290
291         bpf_ringbuf_submit_dynptr(&ptr, 0);
292         return 0;
293 }
294
295 /* A data slice can't be dereferenced if it wasn't checked for null */
296 SEC("?raw_tp/sys_nanosleep")
297 int data_slice_missing_null_check2(void *ctx)
298 {
299         struct bpf_dynptr ptr;
300         __u64 *data1, *data2;
301
302         bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
303
304         data1 = bpf_dynptr_data(&ptr, 0, 8);
305         data2 = bpf_dynptr_data(&ptr, 0, 8);
306         if (data1)
307                 /* this should fail */
308                 *data2 = 3;
309
310 done:
311         bpf_ringbuf_discard_dynptr(&ptr, 0);
312         return 0;
313 }
314
315 /* Can't pass in a dynptr as an arg to a helper function that doesn't take in a
316  * dynptr argument
317  */
318 SEC("?raw_tp/sys_nanosleep")
319 int invalid_helper1(void *ctx)
320 {
321         struct bpf_dynptr ptr;
322
323         get_map_val_dynptr(&ptr);
324
325         /* this should fail */
326         bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!");
327
328         return 0;
329 }
330
331 /* A dynptr can't be passed into a helper function at a non-zero offset */
332 SEC("?raw_tp/sys_nanosleep")
333 int invalid_helper2(void *ctx)
334 {
335         struct bpf_dynptr ptr;
336         char read_data[64];
337
338         get_map_val_dynptr(&ptr);
339
340         /* this should fail */
341         bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0);
342
343         return 0;
344 }
345
346 /* A bpf_dynptr is invalidated if it's been written into */
347 SEC("?raw_tp/sys_nanosleep")
348 int invalid_write1(void *ctx)
349 {
350         struct bpf_dynptr ptr;
351         void *data;
352         __u8 x = 0;
353
354         get_map_val_dynptr(&ptr);
355
356         memcpy(&ptr, &x, sizeof(x));
357
358         /* this should fail */
359         data = bpf_dynptr_data(&ptr, 0, 1);
360
361         return 0;
362 }
363
364 /*
365  * A bpf_dynptr can't be used as a dynptr if it has been written into at a fixed
366  * offset
367  */
368 SEC("?raw_tp/sys_nanosleep")
369 int invalid_write2(void *ctx)
370 {
371         struct bpf_dynptr ptr;
372         char read_data[64];
373         __u8 x = 0;
374
375         bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
376
377         memcpy((void *)&ptr + 8, &x, sizeof(x));
378
379         /* this should fail */
380         bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
381
382         bpf_ringbuf_submit_dynptr(&ptr, 0);
383
384         return 0;
385 }
386
387 /*
388  * A bpf_dynptr can't be used as a dynptr if it has been written into at a
389  * non-const offset
390  */
391 SEC("?raw_tp/sys_nanosleep")
392 int invalid_write3(void *ctx)
393 {
394         struct bpf_dynptr ptr;
395         char stack_buf[16];
396         unsigned long len;
397         __u8 x = 0;
398
399         bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
400
401         memcpy(stack_buf, &val, sizeof(val));
402         len = stack_buf[0] & 0xf;
403
404         memcpy((void *)&ptr + len, &x, sizeof(x));
405
406         /* this should fail */
407         bpf_ringbuf_submit_dynptr(&ptr, 0);
408
409         return 0;
410 }
411
412 static int invalid_write4_callback(__u32 index, void *data)
413 {
414         *(__u32 *)data = 123;
415
416         return 0;
417 }
418
419 /* If the dynptr is written into in a callback function, it should
420  * be invalidated as a dynptr
421  */
422 SEC("?raw_tp/sys_nanosleep")
423 int invalid_write4(void *ctx)
424 {
425         struct bpf_dynptr ptr;
426
427         bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
428
429         bpf_loop(10, invalid_write4_callback, &ptr, 0);
430
431         /* this should fail */
432         bpf_ringbuf_submit_dynptr(&ptr, 0);
433
434         return 0;
435 }
436
437 /* A globally-defined bpf_dynptr can't be used (it must reside as a stack frame) */
438 struct bpf_dynptr global_dynptr;
439 SEC("?raw_tp/sys_nanosleep")
440 int global(void *ctx)
441 {
442         /* this should fail */
443         bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr);
444
445         bpf_ringbuf_discard_dynptr(&global_dynptr, 0);
446
447         return 0;
448 }
449
450 /* A direct read should fail */
451 SEC("?raw_tp/sys_nanosleep")
452 int invalid_read1(void *ctx)
453 {
454         struct bpf_dynptr ptr;
455
456         bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
457
458         /* this should fail */
459         val = *(int *)&ptr;
460
461         bpf_ringbuf_discard_dynptr(&ptr, 0);
462
463         return 0;
464 }
465
466 /* A direct read at an offset should fail */
467 SEC("?raw_tp/sys_nanosleep")
468 int invalid_read2(void *ctx)
469 {
470         struct bpf_dynptr ptr;
471         char read_data[64];
472
473         get_map_val_dynptr(&ptr);
474
475         /* this should fail */
476         bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0);
477
478         return 0;
479 }
480
481 /* A direct read at an offset into the lower stack slot should fail */
482 SEC("?raw_tp/sys_nanosleep")
483 int invalid_read3(void *ctx)
484 {
485         struct bpf_dynptr ptr1, ptr2;
486
487         bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1);
488         bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2);
489
490         /* this should fail */
491         memcpy(&val, (void *)&ptr1 + 8, sizeof(val));
492
493         bpf_ringbuf_discard_dynptr(&ptr1, 0);
494         bpf_ringbuf_discard_dynptr(&ptr2, 0);
495
496         return 0;
497 }
498
499 static int invalid_read4_callback(__u32 index, void *data)
500 {
501         /* this should fail */
502         val = *(__u32 *)data;
503
504         return 0;
505 }
506
507 /* A direct read within a callback function should fail */
508 SEC("?raw_tp/sys_nanosleep")
509 int invalid_read4(void *ctx)
510 {
511         struct bpf_dynptr ptr;
512
513         bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
514
515         bpf_loop(10, invalid_read4_callback, &ptr, 0);
516
517         bpf_ringbuf_submit_dynptr(&ptr, 0);
518
519         return 0;
520 }
521
522 /* Initializing a dynptr on an offset should fail */
523 SEC("?raw_tp/sys_nanosleep")
524 int invalid_offset(void *ctx)
525 {
526         struct bpf_dynptr ptr;
527
528         /* this should fail */
529         bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1);
530
531         bpf_ringbuf_discard_dynptr(&ptr, 0);
532
533         return 0;
534 }
535
536 /* Can't release a dynptr twice */
537 SEC("?raw_tp/sys_nanosleep")
538 int release_twice(void *ctx)
539 {
540         struct bpf_dynptr ptr;
541
542         bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
543
544         bpf_ringbuf_discard_dynptr(&ptr, 0);
545
546         /* this second release should fail */
547         bpf_ringbuf_discard_dynptr(&ptr, 0);
548
549         return 0;
550 }
551
552 static int release_twice_callback_fn(__u32 index, void *data)
553 {
554         /* this should fail */
555         bpf_ringbuf_discard_dynptr(data, 0);
556
557         return 0;
558 }
559
560 /* Test that releasing a dynptr twice, where one of the releases happens
561  * within a calback function, fails
562  */
563 SEC("?raw_tp/sys_nanosleep")
564 int release_twice_callback(void *ctx)
565 {
566         struct bpf_dynptr ptr;
567
568         bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr);
569
570         bpf_ringbuf_discard_dynptr(&ptr, 0);
571
572         bpf_loop(10, release_twice_callback_fn, &ptr, 0);
573
574         return 0;
575 }
576
577 /* Reject unsupported local mem types for dynptr_from_mem API */
578 SEC("?raw_tp/sys_nanosleep")
579 int dynptr_from_mem_invalid_api(void *ctx)
580 {
581         struct bpf_dynptr ptr;
582         int x = 0;
583
584         /* this should fail */
585         bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr);
586
587         return 0;
588 }