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=1") 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=2") 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("Expected an initialized dynptr as arg #3") 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("Expected an initialized dynptr as arg #3") 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("Expected an initialized dynptr as arg #1") 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("arg 1 is an unacquired reference") 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("invalid write to stack") 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 } 656