0001
0002
0003
0004 #include <errno.h>
0005 #include <string.h>
0006 #include <linux/bpf.h>
0007 #include <bpf/bpf_helpers.h>
0008 #include "bpf_misc.h"
0009
0010 char _license[] SEC("license") = "GPL";
0011
0012 struct test_info {
0013 int x;
0014 struct bpf_dynptr ptr;
0015 };
0016
0017 struct {
0018 __uint(type, BPF_MAP_TYPE_ARRAY);
0019 __uint(max_entries, 1);
0020 __type(key, __u32);
0021 __type(value, struct bpf_dynptr);
0022 } array_map1 SEC(".maps");
0023
0024 struct {
0025 __uint(type, BPF_MAP_TYPE_ARRAY);
0026 __uint(max_entries, 1);
0027 __type(key, __u32);
0028 __type(value, struct test_info);
0029 } array_map2 SEC(".maps");
0030
0031 struct {
0032 __uint(type, BPF_MAP_TYPE_ARRAY);
0033 __uint(max_entries, 1);
0034 __type(key, __u32);
0035 __type(value, __u32);
0036 } array_map3 SEC(".maps");
0037
0038 struct sample {
0039 int pid;
0040 long value;
0041 char comm[16];
0042 };
0043
0044 struct {
0045 __uint(type, BPF_MAP_TYPE_RINGBUF);
0046 } ringbuf SEC(".maps");
0047
0048 int err, val;
0049
0050 static int get_map_val_dynptr(struct bpf_dynptr *ptr)
0051 {
0052 __u32 key = 0, *map_val;
0053
0054 bpf_map_update_elem(&array_map3, &key, &val, 0);
0055
0056 map_val = bpf_map_lookup_elem(&array_map3, &key);
0057 if (!map_val)
0058 return -ENOENT;
0059
0060 bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr);
0061
0062 return 0;
0063 }
0064
0065
0066
0067
0068 SEC("?raw_tp/sys_nanosleep")
0069 int ringbuf_missing_release1(void *ctx)
0070 {
0071 struct bpf_dynptr ptr;
0072
0073 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
0074
0075
0076
0077 return 0;
0078 }
0079
0080 SEC("?raw_tp/sys_nanosleep")
0081 int ringbuf_missing_release2(void *ctx)
0082 {
0083 struct bpf_dynptr ptr1, ptr2;
0084 struct sample *sample;
0085
0086 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1);
0087 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2);
0088
0089 sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample));
0090 if (!sample) {
0091 bpf_ringbuf_discard_dynptr(&ptr1, 0);
0092 bpf_ringbuf_discard_dynptr(&ptr2, 0);
0093 return 0;
0094 }
0095
0096 bpf_ringbuf_submit_dynptr(&ptr1, 0);
0097
0098
0099
0100 return 0;
0101 }
0102
0103 static int missing_release_callback_fn(__u32 index, void *data)
0104 {
0105 struct bpf_dynptr ptr;
0106
0107 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
0108
0109
0110
0111 return 0;
0112 }
0113
0114
0115 SEC("?raw_tp/sys_nanosleep")
0116 int ringbuf_missing_release_callback(void *ctx)
0117 {
0118 bpf_loop(10, missing_release_callback_fn, NULL, 0);
0119 return 0;
0120 }
0121
0122
0123 SEC("?raw_tp/sys_nanosleep")
0124 int ringbuf_release_uninit_dynptr(void *ctx)
0125 {
0126 struct bpf_dynptr ptr;
0127
0128
0129 bpf_ringbuf_submit_dynptr(&ptr, 0);
0130
0131 return 0;
0132 }
0133
0134
0135 SEC("?raw_tp/sys_nanosleep")
0136 int use_after_invalid(void *ctx)
0137 {
0138 struct bpf_dynptr ptr;
0139 char read_data[64];
0140
0141 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr);
0142
0143 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
0144
0145 bpf_ringbuf_submit_dynptr(&ptr, 0);
0146
0147
0148 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
0149
0150 return 0;
0151 }
0152
0153
0154 SEC("?raw_tp/sys_nanosleep")
0155 int ringbuf_invalid_api(void *ctx)
0156 {
0157 struct bpf_dynptr ptr;
0158 struct sample *sample;
0159
0160 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
0161 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
0162 if (!sample)
0163 goto done;
0164
0165 sample->pid = 123;
0166
0167
0168 bpf_ringbuf_submit(sample, 0);
0169
0170 done:
0171 bpf_ringbuf_discard_dynptr(&ptr, 0);
0172 return 0;
0173 }
0174
0175
0176 SEC("?raw_tp/sys_nanosleep")
0177 int add_dynptr_to_map1(void *ctx)
0178 {
0179 struct bpf_dynptr ptr;
0180 int key = 0;
0181
0182 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr);
0183
0184
0185 bpf_map_update_elem(&array_map1, &key, &ptr, 0);
0186
0187 bpf_ringbuf_submit_dynptr(&ptr, 0);
0188
0189 return 0;
0190 }
0191
0192
0193 SEC("?raw_tp/sys_nanosleep")
0194 int add_dynptr_to_map2(void *ctx)
0195 {
0196 struct test_info x;
0197 int key = 0;
0198
0199 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr);
0200
0201
0202 bpf_map_update_elem(&array_map2, &key, &x, 0);
0203
0204 bpf_ringbuf_submit_dynptr(&x.ptr, 0);
0205
0206 return 0;
0207 }
0208
0209
0210 SEC("?raw_tp/sys_nanosleep")
0211 int data_slice_out_of_bounds_ringbuf(void *ctx)
0212 {
0213 struct bpf_dynptr ptr;
0214 void *data;
0215
0216 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
0217
0218 data = bpf_dynptr_data(&ptr, 0, 8);
0219 if (!data)
0220 goto done;
0221
0222
0223 val = *((char *)data + 8);
0224
0225 done:
0226 bpf_ringbuf_submit_dynptr(&ptr, 0);
0227 return 0;
0228 }
0229
0230 SEC("?raw_tp/sys_nanosleep")
0231 int data_slice_out_of_bounds_map_value(void *ctx)
0232 {
0233 __u32 key = 0, map_val;
0234 struct bpf_dynptr ptr;
0235 void *data;
0236
0237 get_map_val_dynptr(&ptr);
0238
0239 data = bpf_dynptr_data(&ptr, 0, sizeof(map_val));
0240 if (!data)
0241 return 0;
0242
0243
0244 val = *((char *)data + (sizeof(map_val) + 1));
0245
0246 return 0;
0247 }
0248
0249
0250 SEC("?raw_tp/sys_nanosleep")
0251 int data_slice_use_after_release(void *ctx)
0252 {
0253 struct bpf_dynptr ptr;
0254 struct sample *sample;
0255
0256 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr);
0257 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample));
0258 if (!sample)
0259 goto done;
0260
0261 sample->pid = 123;
0262
0263 bpf_ringbuf_submit_dynptr(&ptr, 0);
0264
0265
0266 val = sample->pid;
0267
0268 return 0;
0269
0270 done:
0271 bpf_ringbuf_discard_dynptr(&ptr, 0);
0272 return 0;
0273 }
0274
0275
0276 SEC("?raw_tp/sys_nanosleep")
0277 int data_slice_missing_null_check1(void *ctx)
0278 {
0279 struct bpf_dynptr ptr;
0280 void *data;
0281
0282 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
0283
0284 data = bpf_dynptr_data(&ptr, 0, 8);
0285
0286
0287
0288
0289 *(__u8 *)data = 3;
0290
0291 bpf_ringbuf_submit_dynptr(&ptr, 0);
0292 return 0;
0293 }
0294
0295
0296 SEC("?raw_tp/sys_nanosleep")
0297 int data_slice_missing_null_check2(void *ctx)
0298 {
0299 struct bpf_dynptr ptr;
0300 __u64 *data1, *data2;
0301
0302 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
0303
0304 data1 = bpf_dynptr_data(&ptr, 0, 8);
0305 data2 = bpf_dynptr_data(&ptr, 0, 8);
0306 if (data1)
0307
0308 *data2 = 3;
0309
0310 done:
0311 bpf_ringbuf_discard_dynptr(&ptr, 0);
0312 return 0;
0313 }
0314
0315
0316
0317
0318 SEC("?raw_tp/sys_nanosleep")
0319 int invalid_helper1(void *ctx)
0320 {
0321 struct bpf_dynptr ptr;
0322
0323 get_map_val_dynptr(&ptr);
0324
0325
0326 bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!");
0327
0328 return 0;
0329 }
0330
0331
0332 SEC("?raw_tp/sys_nanosleep")
0333 int invalid_helper2(void *ctx)
0334 {
0335 struct bpf_dynptr ptr;
0336 char read_data[64];
0337
0338 get_map_val_dynptr(&ptr);
0339
0340
0341 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0);
0342
0343 return 0;
0344 }
0345
0346
0347 SEC("?raw_tp/sys_nanosleep")
0348 int invalid_write1(void *ctx)
0349 {
0350 struct bpf_dynptr ptr;
0351 void *data;
0352 __u8 x = 0;
0353
0354 get_map_val_dynptr(&ptr);
0355
0356 memcpy(&ptr, &x, sizeof(x));
0357
0358
0359 data = bpf_dynptr_data(&ptr, 0, 1);
0360
0361 return 0;
0362 }
0363
0364
0365
0366
0367
0368 SEC("?raw_tp/sys_nanosleep")
0369 int invalid_write2(void *ctx)
0370 {
0371 struct bpf_dynptr ptr;
0372 char read_data[64];
0373 __u8 x = 0;
0374
0375 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
0376
0377 memcpy((void *)&ptr + 8, &x, sizeof(x));
0378
0379
0380 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0);
0381
0382 bpf_ringbuf_submit_dynptr(&ptr, 0);
0383
0384 return 0;
0385 }
0386
0387
0388
0389
0390
0391 SEC("?raw_tp/sys_nanosleep")
0392 int invalid_write3(void *ctx)
0393 {
0394 struct bpf_dynptr ptr;
0395 char stack_buf[16];
0396 unsigned long len;
0397 __u8 x = 0;
0398
0399 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr);
0400
0401 memcpy(stack_buf, &val, sizeof(val));
0402 len = stack_buf[0] & 0xf;
0403
0404 memcpy((void *)&ptr + len, &x, sizeof(x));
0405
0406
0407 bpf_ringbuf_submit_dynptr(&ptr, 0);
0408
0409 return 0;
0410 }
0411
0412 static int invalid_write4_callback(__u32 index, void *data)
0413 {
0414 *(__u32 *)data = 123;
0415
0416 return 0;
0417 }
0418
0419
0420
0421
0422 SEC("?raw_tp/sys_nanosleep")
0423 int invalid_write4(void *ctx)
0424 {
0425 struct bpf_dynptr ptr;
0426
0427 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
0428
0429 bpf_loop(10, invalid_write4_callback, &ptr, 0);
0430
0431
0432 bpf_ringbuf_submit_dynptr(&ptr, 0);
0433
0434 return 0;
0435 }
0436
0437
0438 struct bpf_dynptr global_dynptr;
0439 SEC("?raw_tp/sys_nanosleep")
0440 int global(void *ctx)
0441 {
0442
0443 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr);
0444
0445 bpf_ringbuf_discard_dynptr(&global_dynptr, 0);
0446
0447 return 0;
0448 }
0449
0450
0451 SEC("?raw_tp/sys_nanosleep")
0452 int invalid_read1(void *ctx)
0453 {
0454 struct bpf_dynptr ptr;
0455
0456 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
0457
0458
0459 val = *(int *)&ptr;
0460
0461 bpf_ringbuf_discard_dynptr(&ptr, 0);
0462
0463 return 0;
0464 }
0465
0466
0467 SEC("?raw_tp/sys_nanosleep")
0468 int invalid_read2(void *ctx)
0469 {
0470 struct bpf_dynptr ptr;
0471 char read_data[64];
0472
0473 get_map_val_dynptr(&ptr);
0474
0475
0476 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0);
0477
0478 return 0;
0479 }
0480
0481
0482 SEC("?raw_tp/sys_nanosleep")
0483 int invalid_read3(void *ctx)
0484 {
0485 struct bpf_dynptr ptr1, ptr2;
0486
0487 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1);
0488 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2);
0489
0490
0491 memcpy(&val, (void *)&ptr1 + 8, sizeof(val));
0492
0493 bpf_ringbuf_discard_dynptr(&ptr1, 0);
0494 bpf_ringbuf_discard_dynptr(&ptr2, 0);
0495
0496 return 0;
0497 }
0498
0499 static int invalid_read4_callback(__u32 index, void *data)
0500 {
0501
0502 val = *(__u32 *)data;
0503
0504 return 0;
0505 }
0506
0507
0508 SEC("?raw_tp/sys_nanosleep")
0509 int invalid_read4(void *ctx)
0510 {
0511 struct bpf_dynptr ptr;
0512
0513 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr);
0514
0515 bpf_loop(10, invalid_read4_callback, &ptr, 0);
0516
0517 bpf_ringbuf_submit_dynptr(&ptr, 0);
0518
0519 return 0;
0520 }
0521
0522
0523 SEC("?raw_tp/sys_nanosleep")
0524 int invalid_offset(void *ctx)
0525 {
0526 struct bpf_dynptr ptr;
0527
0528
0529 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1);
0530
0531 bpf_ringbuf_discard_dynptr(&ptr, 0);
0532
0533 return 0;
0534 }
0535
0536
0537 SEC("?raw_tp/sys_nanosleep")
0538 int release_twice(void *ctx)
0539 {
0540 struct bpf_dynptr ptr;
0541
0542 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr);
0543
0544 bpf_ringbuf_discard_dynptr(&ptr, 0);
0545
0546
0547 bpf_ringbuf_discard_dynptr(&ptr, 0);
0548
0549 return 0;
0550 }
0551
0552 static int release_twice_callback_fn(__u32 index, void *data)
0553 {
0554
0555 bpf_ringbuf_discard_dynptr(data, 0);
0556
0557 return 0;
0558 }
0559
0560
0561
0562
0563 SEC("?raw_tp/sys_nanosleep")
0564 int release_twice_callback(void *ctx)
0565 {
0566 struct bpf_dynptr ptr;
0567
0568 bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr);
0569
0570 bpf_ringbuf_discard_dynptr(&ptr, 0);
0571
0572 bpf_loop(10, release_twice_callback_fn, &ptr, 0);
0573
0574 return 0;
0575 }
0576
0577
0578 SEC("?raw_tp/sys_nanosleep")
0579 int dynptr_from_mem_invalid_api(void *ctx)
0580 {
0581 struct bpf_dynptr ptr;
0582 int x = 0;
0583
0584
0585 bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr);
0586
0587 return 0;
0588 }