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