1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2022 Facebook */ 3 4 #include <errno.h> 5 #include <string.h> 6 #include <stdbool.h> 7 #include <linux/bpf.h> 8 #include <bpf/bpf_helpers.h> 9 #include <bpf/bpf_tracing.h> 10 #include <linux/if_ether.h> 11 #include "bpf_misc.h" 12 #include "bpf_kfuncs.h" 13 14 char _license[] SEC("license") = "GPL"; 15 16 struct test_info { 17 int x; 18 struct bpf_dynptr ptr; 19 }; 20 21 struct { 22 __uint(type, BPF_MAP_TYPE_ARRAY); 23 __uint(max_entries, 1); 24 __type(key, __u32); 25 __type(value, struct bpf_dynptr); 26 } array_map1 SEC(".maps"); 27 28 struct { 29 __uint(type, BPF_MAP_TYPE_ARRAY); 30 __uint(max_entries, 1); 31 __type(key, __u32); 32 __type(value, struct test_info); 33 } array_map2 SEC(".maps"); 34 35 struct { 36 __uint(type, BPF_MAP_TYPE_ARRAY); 37 __uint(max_entries, 1); 38 __type(key, __u32); 39 __type(value, __u32); 40 } array_map3 SEC(".maps"); 41 42 struct { 43 __uint(type, BPF_MAP_TYPE_ARRAY); 44 __uint(max_entries, 1); 45 __type(key, __u32); 46 __type(value, __u64); 47 } array_map4 SEC(".maps"); 48 49 struct sample { 50 int pid; 51 long value; 52 char comm[16]; 53 }; 54 55 struct { 56 __uint(type, BPF_MAP_TYPE_RINGBUF); 57 __uint(max_entries, 4096); 58 } ringbuf SEC(".maps"); 59 60 int err, val; 61 62 static int get_map_val_dynptr(struct bpf_dynptr *ptr) 63 { 64 __u32 key = 0, *map_val; 65 66 bpf_map_update_elem(&array_map3, &key, &val, 0); 67 68 map_val = bpf_map_lookup_elem(&array_map3, &key); 69 if (!map_val) 70 return -ENOENT; 71 72 bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr); 73 74 return 0; 75 } 76 77 /* Every bpf_ringbuf_reserve_dynptr call must have a corresponding 78 * bpf_ringbuf_submit/discard_dynptr call 79 */ 80 SEC("?raw_tp") 81 __failure __msg("Unreleased reference id=1") 82 int ringbuf_missing_release1(void *ctx) 83 { 84 struct bpf_dynptr ptr = {}; 85 86 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 87 88 /* missing a call to bpf_ringbuf_discard/submit_dynptr */ 89 90 return 0; 91 } 92 93 SEC("?raw_tp") 94 __failure __msg("Unreleased reference id=3") 95 int ringbuf_missing_release2(void *ctx) 96 { 97 struct bpf_dynptr ptr1, ptr2; 98 struct sample *sample; 99 100 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1); 101 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2); 102 103 sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample)); 104 if (!sample) { 105 bpf_ringbuf_discard_dynptr(&ptr1, 0); 106 bpf_ringbuf_discard_dynptr(&ptr2, 0); 107 return 0; 108 } 109 110 bpf_ringbuf_submit_dynptr(&ptr1, 0); 111 112 /* missing a call to bpf_ringbuf_discard/submit_dynptr on ptr2 */ 113 114 return 0; 115 } 116 117 static int missing_release_callback_fn(__u32 index, void *data) 118 { 119 struct bpf_dynptr ptr; 120 121 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 122 123 /* missing a call to bpf_ringbuf_discard/submit_dynptr */ 124 125 return 0; 126 } 127 128 /* A callback cannot return with the last dynptr for a referenced resource. */ 129 SEC("?raw_tp") 130 __failure __msg("cannot overwrite referenced dynptr") 131 int ringbuf_missing_release_callback(void *ctx) 132 { 133 bpf_loop(10, missing_release_callback_fn, NULL, 0); 134 return 0; 135 } 136 137 /* Can't call bpf_ringbuf_submit/discard_dynptr on a non-initialized dynptr */ 138 SEC("?raw_tp") 139 __failure __msg("Expected an initialized dynptr as R1") 140 int ringbuf_release_uninit_dynptr(void *ctx) 141 { 142 struct bpf_dynptr ptr; 143 144 /* this should fail */ 145 bpf_ringbuf_submit_dynptr(&ptr, 0); 146 147 return 0; 148 } 149 150 /* A dynptr can't be used after it has been invalidated */ 151 SEC("?raw_tp") 152 __failure __msg("Expected an initialized dynptr as R3") 153 int use_after_invalid(void *ctx) 154 { 155 struct bpf_dynptr ptr; 156 char read_data[64]; 157 158 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr); 159 160 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 161 162 bpf_ringbuf_submit_dynptr(&ptr, 0); 163 164 /* this should fail */ 165 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 166 167 return 0; 168 } 169 170 /* Can't call non-dynptr ringbuf APIs on a dynptr ringbuf sample */ 171 SEC("?raw_tp") 172 __failure __msg("type=mem expected=ringbuf_mem") 173 int ringbuf_invalid_api(void *ctx) 174 { 175 struct bpf_dynptr ptr; 176 struct sample *sample; 177 178 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr); 179 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample)); 180 if (!sample) 181 goto done; 182 183 sample->pid = 123; 184 185 /* invalid API use. need to use dynptr API to submit/discard */ 186 bpf_ringbuf_submit(sample, 0); 187 188 done: 189 bpf_ringbuf_discard_dynptr(&ptr, 0); 190 return 0; 191 } 192 193 /* Can't add a dynptr to a map */ 194 SEC("?raw_tp") 195 __failure __msg("invalid read from stack") 196 int add_dynptr_to_map1(void *ctx) 197 { 198 struct bpf_dynptr ptr; 199 int key = 0; 200 201 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 202 203 /* this should fail */ 204 bpf_map_update_elem(&array_map1, &key, &ptr, 0); 205 206 bpf_ringbuf_submit_dynptr(&ptr, 0); 207 208 return 0; 209 } 210 211 /* Can't add a struct with an embedded dynptr to a map */ 212 SEC("?raw_tp") 213 __failure __msg("invalid read from stack") 214 int add_dynptr_to_map2(void *ctx) 215 { 216 struct test_info x; 217 int key = 0; 218 219 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr); 220 221 /* this should fail */ 222 bpf_map_update_elem(&array_map2, &key, &x, 0); 223 224 bpf_ringbuf_submit_dynptr(&x.ptr, 0); 225 226 return 0; 227 } 228 229 /* A data slice can't be accessed out of bounds */ 230 SEC("?raw_tp") 231 __failure __msg("value is outside of the allowed memory range") 232 int data_slice_out_of_bounds_ringbuf(void *ctx) 233 { 234 struct bpf_dynptr ptr; 235 void *data; 236 237 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr); 238 239 data = bpf_dynptr_data(&ptr, 0, 8); 240 if (!data) 241 goto done; 242 243 /* can't index out of bounds of the data slice */ 244 val = *((char *)data + 8); 245 246 done: 247 bpf_ringbuf_submit_dynptr(&ptr, 0); 248 return 0; 249 } 250 251 /* A data slice can't be accessed out of bounds */ 252 SEC("?tc") 253 __failure __msg("value is outside of the allowed memory range") 254 int data_slice_out_of_bounds_skb(struct __sk_buff *skb) 255 { 256 struct bpf_dynptr ptr; 257 struct ethhdr *hdr; 258 char buffer[sizeof(*hdr)] = {}; 259 260 bpf_dynptr_from_skb(skb, 0, &ptr); 261 262 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 263 if (!hdr) 264 return SK_DROP; 265 266 /* this should fail */ 267 *(__u8*)(hdr + 1) = 1; 268 269 return SK_PASS; 270 } 271 272 /* A metadata slice can't be accessed out of bounds */ 273 SEC("?tc") 274 __failure __msg("value is outside of the allowed memory range") 275 int data_slice_out_of_bounds_skb_meta(struct __sk_buff *skb) 276 { 277 struct bpf_dynptr meta; 278 __u8 *md; 279 280 bpf_dynptr_from_skb_meta(skb, 0, &meta); 281 282 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md)); 283 if (!md) 284 return SK_DROP; 285 286 /* this should fail */ 287 *(md + 1) = 42; 288 289 return SK_PASS; 290 } 291 292 SEC("?raw_tp") 293 __failure __msg("value is outside of the allowed memory range") 294 int data_slice_out_of_bounds_map_value(void *ctx) 295 { 296 __u32 map_val; 297 struct bpf_dynptr ptr; 298 void *data; 299 300 get_map_val_dynptr(&ptr); 301 302 data = bpf_dynptr_data(&ptr, 0, sizeof(map_val)); 303 if (!data) 304 return 0; 305 306 /* can't index out of bounds of the data slice */ 307 val = *((char *)data + (sizeof(map_val) + 1)); 308 309 return 0; 310 } 311 312 /* A data slice can't be used after it has been released */ 313 SEC("?raw_tp") 314 __failure __msg("invalid mem access 'scalar'") 315 int data_slice_use_after_release1(void *ctx) 316 { 317 struct bpf_dynptr ptr; 318 struct sample *sample; 319 320 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr); 321 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample)); 322 if (!sample) 323 goto done; 324 325 sample->pid = 123; 326 327 bpf_ringbuf_submit_dynptr(&ptr, 0); 328 329 /* this should fail */ 330 val = sample->pid; 331 332 return 0; 333 334 done: 335 bpf_ringbuf_discard_dynptr(&ptr, 0); 336 return 0; 337 } 338 339 /* A data slice can't be used after it has been released. 340 * 341 * This tests the case where the data slice tracks a dynptr (ptr2) 342 * that is at a non-zero offset from the frame pointer (ptr1 is at fp, 343 * ptr2 is at fp - 16). 344 */ 345 SEC("?raw_tp") 346 __failure __msg("invalid mem access 'scalar'") 347 int data_slice_use_after_release2(void *ctx) 348 { 349 struct bpf_dynptr ptr1, ptr2; 350 struct sample *sample; 351 352 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr1); 353 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2); 354 355 sample = bpf_dynptr_data(&ptr2, 0, sizeof(*sample)); 356 if (!sample) 357 goto done; 358 359 sample->pid = 23; 360 361 bpf_ringbuf_submit_dynptr(&ptr2, 0); 362 363 /* this should fail */ 364 sample->pid = 23; 365 366 bpf_ringbuf_submit_dynptr(&ptr1, 0); 367 368 return 0; 369 370 done: 371 bpf_ringbuf_discard_dynptr(&ptr2, 0); 372 bpf_ringbuf_discard_dynptr(&ptr1, 0); 373 return 0; 374 } 375 376 /* A data slice must be first checked for NULL */ 377 SEC("?raw_tp") 378 __failure __msg("invalid mem access 'mem_or_null'") 379 int data_slice_missing_null_check1(void *ctx) 380 { 381 struct bpf_dynptr ptr; 382 void *data; 383 384 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr); 385 386 data = bpf_dynptr_data(&ptr, 0, 8); 387 388 /* missing if (!data) check */ 389 390 /* this should fail */ 391 *(__u8 *)data = 3; 392 393 bpf_ringbuf_submit_dynptr(&ptr, 0); 394 return 0; 395 } 396 397 /* A data slice can't be dereferenced if it wasn't checked for null */ 398 SEC("?raw_tp") 399 __failure __msg("invalid mem access 'mem_or_null'") 400 int data_slice_missing_null_check2(void *ctx) 401 { 402 struct bpf_dynptr ptr; 403 __u64 *data1, *data2; 404 405 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr); 406 407 data1 = bpf_dynptr_data(&ptr, 0, 8); 408 data2 = bpf_dynptr_data(&ptr, 0, 8); 409 if (data1) 410 /* this should fail */ 411 *data2 = 3; 412 413 bpf_ringbuf_discard_dynptr(&ptr, 0); 414 return 0; 415 } 416 417 /* Can't pass in a dynptr as an arg to a helper function that doesn't take in a 418 * dynptr argument 419 */ 420 SEC("?raw_tp") 421 __failure __msg("invalid read from stack") 422 int invalid_helper1(void *ctx) 423 { 424 struct bpf_dynptr ptr; 425 426 get_map_val_dynptr(&ptr); 427 428 /* this should fail */ 429 bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!"); 430 431 return 0; 432 } 433 434 /* A dynptr can't be passed into a helper function at a non-zero offset */ 435 SEC("?raw_tp") 436 __failure __msg("cannot pass in dynptr at an offset=-8") 437 int invalid_helper2(void *ctx) 438 { 439 struct bpf_dynptr ptr; 440 char read_data[64]; 441 442 get_map_val_dynptr(&ptr); 443 444 /* this should fail */ 445 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0); 446 return 0; 447 } 448 449 /* A bpf_dynptr is invalidated if it's been written into */ 450 SEC("?raw_tp") 451 __failure __msg("Expected an initialized dynptr as R1") 452 int invalid_write1(void *ctx) 453 { 454 struct bpf_dynptr ptr; 455 void *data; 456 __u8 x = 0; 457 458 get_map_val_dynptr(&ptr); 459 460 memcpy(&ptr, &x, sizeof(x)); 461 462 /* this should fail */ 463 data = bpf_dynptr_data(&ptr, 0, 1); 464 __sink(data); 465 466 return 0; 467 } 468 469 /* 470 * A bpf_dynptr can't be used as a dynptr if it has been written into at a fixed 471 * offset 472 */ 473 SEC("?raw_tp") 474 __failure __msg("cannot overwrite referenced dynptr") 475 int invalid_write2(void *ctx) 476 { 477 struct bpf_dynptr ptr; 478 char read_data[64]; 479 __u8 x = 0; 480 481 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 482 483 memcpy((void *)&ptr + 8, &x, sizeof(x)); 484 485 /* this should fail */ 486 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 487 488 bpf_ringbuf_submit_dynptr(&ptr, 0); 489 490 return 0; 491 } 492 493 /* 494 * A bpf_dynptr can't be used as a dynptr if it has been written into at a 495 * non-const offset 496 */ 497 SEC("?raw_tp") 498 __failure __msg("cannot overwrite referenced dynptr") 499 int invalid_write3(void *ctx) 500 { 501 struct bpf_dynptr ptr; 502 char stack_buf[16]; 503 unsigned long len; 504 __u8 x = 0; 505 506 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr); 507 508 memcpy(stack_buf, &val, sizeof(val)); 509 len = stack_buf[0] & 0xf; 510 511 memcpy((void *)&ptr + len, &x, sizeof(x)); 512 513 /* this should fail */ 514 bpf_ringbuf_submit_dynptr(&ptr, 0); 515 516 return 0; 517 } 518 519 static int invalid_write4_callback(__u32 index, void *data) 520 { 521 *(__u32 *)data = 123; 522 523 return 0; 524 } 525 526 /* If the dynptr is written into in a callback function, it should 527 * be invalidated as a dynptr 528 */ 529 SEC("?raw_tp") 530 __failure __msg("cannot overwrite referenced dynptr") 531 int invalid_write4(void *ctx) 532 { 533 struct bpf_dynptr ptr; 534 535 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 536 537 bpf_loop(10, invalid_write4_callback, &ptr, 0); 538 539 /* this should fail */ 540 bpf_ringbuf_submit_dynptr(&ptr, 0); 541 542 return 0; 543 } 544 545 /* A globally-defined bpf_dynptr can't be used (it must reside as a stack frame) */ 546 struct bpf_dynptr global_dynptr; 547 548 SEC("?raw_tp") 549 __failure __msg("type=map_value expected=fp") 550 int global(void *ctx) 551 { 552 /* this should fail */ 553 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr); 554 555 bpf_ringbuf_discard_dynptr(&global_dynptr, 0); 556 557 return 0; 558 } 559 560 /* A direct read should fail */ 561 SEC("?raw_tp") 562 __failure __msg("invalid read from stack") 563 __msg("Verification failed: Memory Safety: Direct read of dynptr stack state") 564 __msg("verifier-managed dynptr state") 565 __msg("Use dynptr helpers or kfuncs") 566 int invalid_read1(void *ctx) 567 { 568 struct bpf_dynptr ptr; 569 570 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 571 572 /* this should fail */ 573 val = *(int *)&ptr; 574 575 bpf_ringbuf_discard_dynptr(&ptr, 0); 576 577 return 0; 578 } 579 580 /* A direct read at an offset should fail */ 581 SEC("?raw_tp") 582 __failure __msg("cannot pass in dynptr at an offset") 583 int invalid_read2(void *ctx) 584 { 585 struct bpf_dynptr ptr; 586 char read_data[64]; 587 588 get_map_val_dynptr(&ptr); 589 590 /* this should fail */ 591 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0); 592 593 return 0; 594 } 595 596 /* A direct read at an offset into the lower stack slot should fail */ 597 SEC("?raw_tp") 598 __failure __msg("invalid read from stack") 599 int invalid_read3(void *ctx) 600 { 601 struct bpf_dynptr ptr1, ptr2; 602 603 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1); 604 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2); 605 606 /* this should fail */ 607 memcpy(&val, (void *)&ptr1 + 8, sizeof(val)); 608 609 bpf_ringbuf_discard_dynptr(&ptr1, 0); 610 bpf_ringbuf_discard_dynptr(&ptr2, 0); 611 612 return 0; 613 } 614 615 static int invalid_read4_callback(__u32 index, void *data) 616 { 617 /* this should fail */ 618 val = *(__u32 *)data; 619 620 return 0; 621 } 622 623 /* A direct read within a callback function should fail */ 624 SEC("?raw_tp") 625 __failure __msg("invalid read from stack") 626 int invalid_read4(void *ctx) 627 { 628 struct bpf_dynptr ptr; 629 630 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 631 632 bpf_loop(10, invalid_read4_callback, &ptr, 0); 633 634 bpf_ringbuf_submit_dynptr(&ptr, 0); 635 636 return 0; 637 } 638 639 /* Initializing a dynptr on an offset should fail */ 640 SEC("?raw_tp") 641 __failure __msg("cannot pass in dynptr at an offset=0") 642 int invalid_offset(void *ctx) 643 { 644 struct bpf_dynptr ptr; 645 646 /* this should fail */ 647 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1); 648 649 bpf_ringbuf_discard_dynptr(&ptr, 0); 650 651 return 0; 652 } 653 654 /* Can't release a dynptr twice */ 655 SEC("?raw_tp") 656 __failure __msg("Expected an initialized dynptr as R1") 657 int release_twice(void *ctx) 658 { 659 struct bpf_dynptr ptr; 660 661 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr); 662 663 bpf_ringbuf_discard_dynptr(&ptr, 0); 664 665 /* this second release should fail */ 666 bpf_ringbuf_discard_dynptr(&ptr, 0); 667 668 return 0; 669 } 670 671 static int release_twice_callback_fn(__u32 index, void *data) 672 { 673 /* this should fail */ 674 bpf_ringbuf_discard_dynptr(data, 0); 675 676 return 0; 677 } 678 679 /* Test that releasing a dynptr twice, where one of the releases happens 680 * within a callback function, fails 681 */ 682 SEC("?raw_tp") 683 __failure __msg("Expected an initialized dynptr as R1") 684 int release_twice_callback(void *ctx) 685 { 686 struct bpf_dynptr ptr; 687 688 bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr); 689 690 bpf_ringbuf_discard_dynptr(&ptr, 0); 691 692 bpf_loop(10, release_twice_callback_fn, &ptr, 0); 693 694 return 0; 695 } 696 697 /* Reject unsupported local mem types for dynptr_from_mem API */ 698 SEC("?raw_tp") 699 __failure __msg("Unsupported reg type fp for bpf_dynptr_from_mem data") 700 int dynptr_from_mem_invalid_api(void *ctx) 701 { 702 struct bpf_dynptr ptr; 703 int x = 0; 704 705 /* this should fail */ 706 bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr); 707 708 return 0; 709 } 710 711 /* Cannot create dynptr from dynptr data */ 712 SEC("?raw_tp") 713 __failure __msg("Unsupported reg type mem for bpf_dynptr_from_mem data") 714 int dynptr_from_dynptr_data(void *ctx) 715 { 716 struct bpf_dynptr ptr, ptr2; 717 __u8 *data; 718 719 if (get_map_val_dynptr(&ptr)) 720 return 0; 721 722 data = bpf_dynptr_data(&ptr, 0, sizeof(__u32)); 723 if (!data) 724 return 0; 725 726 /* this should fail */ 727 bpf_dynptr_from_mem(data, sizeof(__u32), 0, &ptr2); 728 729 return 0; 730 } 731 732 /* Cannot create dynptr from dynptr slice */ 733 SEC("?tc") 734 __failure __msg("Unsupported reg type mem for bpf_dynptr_from_mem data") 735 int dynptr_from_dynptr_slice(struct __sk_buff *skb) 736 { 737 struct bpf_dynptr ptr, ptr2; 738 struct ethhdr *hdr; 739 char buffer[sizeof(*hdr)] = {}; 740 741 bpf_dynptr_from_skb(skb, 0, &ptr); 742 743 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 744 if (!hdr) 745 return SK_DROP; 746 747 /* this should fail */ 748 bpf_dynptr_from_mem(hdr, sizeof(*hdr), 0, &ptr2); 749 750 return SK_PASS; 751 } 752 753 SEC("?tc") 754 __failure __msg("cannot overwrite referenced dynptr") __log_level(2) 755 int dynptr_pruning_overwrite(struct __sk_buff *ctx) 756 { 757 asm volatile ( 758 "r9 = 0xeB9F; \ 759 r6 = %[ringbuf] ll; \ 760 r1 = r6; \ 761 r2 = 8; \ 762 r3 = 0; \ 763 r4 = r10; \ 764 r4 += -16; \ 765 call %[bpf_ringbuf_reserve_dynptr]; \ 766 if r0 == 0 goto pjmp1; \ 767 goto pjmp2; \ 768 pjmp1: \ 769 *(u64 *)(r10 - 16) = r9; \ 770 pjmp2: \ 771 r1 = r10; \ 772 r1 += -16; \ 773 r2 = 0; \ 774 call %[bpf_ringbuf_discard_dynptr]; " 775 : 776 : __imm(bpf_ringbuf_reserve_dynptr), 777 __imm(bpf_ringbuf_discard_dynptr), 778 __imm_addr(ringbuf) 779 : __clobber_all 780 ); 781 return 0; 782 } 783 784 SEC("?tc") 785 __success __msg("12: safe") __log_level(2) 786 int dynptr_pruning_stacksafe(struct __sk_buff *ctx) 787 { 788 asm volatile ( 789 "r9 = 0xeB9F; \ 790 r6 = %[ringbuf] ll; \ 791 r1 = r6; \ 792 r2 = 8; \ 793 r3 = 0; \ 794 r4 = r10; \ 795 r4 += -16; \ 796 call %[bpf_ringbuf_reserve_dynptr]; \ 797 if r0 == 0 goto stjmp1; \ 798 goto stjmp2; \ 799 stjmp1: \ 800 r9 = r9; \ 801 stjmp2: \ 802 r1 = r10; \ 803 r1 += -16; \ 804 r2 = 0; \ 805 call %[bpf_ringbuf_discard_dynptr]; " 806 : 807 : __imm(bpf_ringbuf_reserve_dynptr), 808 __imm(bpf_ringbuf_discard_dynptr), 809 __imm_addr(ringbuf) 810 : __clobber_all 811 ); 812 return 0; 813 } 814 815 SEC("?tc") 816 __failure __msg("cannot overwrite referenced dynptr") __log_level(2) 817 int dynptr_pruning_type_confusion(struct __sk_buff *ctx) 818 { 819 asm volatile ( 820 "r6 = %[array_map4] ll; \ 821 r7 = %[ringbuf] ll; \ 822 r1 = r6; \ 823 r2 = r10; \ 824 r2 += -8; \ 825 r9 = 0; \ 826 *(u64 *)(r2 + 0) = r9; \ 827 r3 = r10; \ 828 r3 += -24; \ 829 r9 = 0xeB9FeB9F; \ 830 *(u64 *)(r10 - 16) = r9; \ 831 *(u64 *)(r10 - 24) = r9; \ 832 r9 = 0; \ 833 r4 = 0; \ 834 r8 = r2; \ 835 call %[bpf_map_update_elem]; \ 836 r1 = r6; \ 837 r2 = r8; \ 838 call %[bpf_map_lookup_elem]; \ 839 if r0 != 0 goto tjmp1; \ 840 exit; \ 841 tjmp1: \ 842 r8 = r0; \ 843 r1 = r7; \ 844 r2 = 8; \ 845 r3 = 0; \ 846 r4 = r10; \ 847 r4 += -16; \ 848 r0 = *(u64 *)(r0 + 0); \ 849 call %[bpf_ringbuf_reserve_dynptr]; \ 850 if r0 == 0 goto tjmp2; \ 851 r8 = r8; \ 852 r8 = r8; \ 853 r8 = r8; \ 854 r8 = r8; \ 855 r8 = r8; \ 856 r8 = r8; \ 857 r8 = r8; \ 858 goto tjmp3; \ 859 tjmp2: \ 860 *(u64 *)(r10 - 8) = r9; \ 861 *(u64 *)(r10 - 16) = r9; \ 862 r1 = r8; \ 863 r1 += 8; \ 864 r2 = 0; \ 865 r3 = 0; \ 866 r4 = r10; \ 867 r4 += -16; \ 868 call %[bpf_dynptr_from_mem]; \ 869 tjmp3: \ 870 r1 = r10; \ 871 r1 += -16; \ 872 r2 = 0; \ 873 call %[bpf_ringbuf_discard_dynptr]; " 874 : 875 : __imm(bpf_map_update_elem), 876 __imm(bpf_map_lookup_elem), 877 __imm(bpf_ringbuf_reserve_dynptr), 878 __imm(bpf_dynptr_from_mem), 879 __imm(bpf_ringbuf_discard_dynptr), 880 __imm_addr(array_map4), 881 __imm_addr(ringbuf) 882 : __clobber_all 883 ); 884 return 0; 885 } 886 887 SEC("?tc") 888 __failure __msg("dynptr has to be at a constant offset") __log_level(2) 889 int dynptr_var_off_overwrite(struct __sk_buff *ctx) 890 { 891 asm volatile ( 892 "r9 = 16; \ 893 *(u32 *)(r10 - 4) = r9; \ 894 r8 = *(u32 *)(r10 - 4); \ 895 if r8 >= 0 goto vjmp1; \ 896 r0 = 1; \ 897 exit; \ 898 vjmp1: \ 899 if r8 <= 16 goto vjmp2; \ 900 r0 = 1; \ 901 exit; \ 902 vjmp2: \ 903 r8 &= 16; \ 904 r1 = %[ringbuf] ll; \ 905 r2 = 8; \ 906 r3 = 0; \ 907 r4 = r10; \ 908 r4 += -32; \ 909 r4 += r8; \ 910 call %[bpf_ringbuf_reserve_dynptr]; \ 911 r9 = 0xeB9F; \ 912 *(u64 *)(r10 - 16) = r9; \ 913 r1 = r10; \ 914 r1 += -32; \ 915 r1 += r8; \ 916 r2 = 0; \ 917 call %[bpf_ringbuf_discard_dynptr]; " 918 : 919 : __imm(bpf_ringbuf_reserve_dynptr), 920 __imm(bpf_ringbuf_discard_dynptr), 921 __imm_addr(ringbuf) 922 : __clobber_all 923 ); 924 return 0; 925 } 926 927 SEC("?tc") 928 __failure __msg("cannot overwrite referenced dynptr") __log_level(2) 929 int dynptr_partial_slot_invalidate(struct __sk_buff *ctx) 930 { 931 asm volatile ( 932 "r6 = %[ringbuf] ll; \ 933 r7 = %[array_map4] ll; \ 934 r1 = r7; \ 935 r2 = r10; \ 936 r2 += -8; \ 937 r9 = 0; \ 938 *(u64 *)(r2 + 0) = r9; \ 939 r3 = r2; \ 940 r4 = 0; \ 941 r8 = r2; \ 942 call %[bpf_map_update_elem]; \ 943 r1 = r7; \ 944 r2 = r8; \ 945 call %[bpf_map_lookup_elem]; \ 946 if r0 != 0 goto sjmp1; \ 947 exit; \ 948 sjmp1: \ 949 r7 = r0; \ 950 r1 = r6; \ 951 r2 = 8; \ 952 r3 = 0; \ 953 r4 = r10; \ 954 r4 += -24; \ 955 call %[bpf_ringbuf_reserve_dynptr]; \ 956 *(u64 *)(r10 - 16) = r9; \ 957 r1 = r7; \ 958 r2 = 8; \ 959 r3 = 0; \ 960 r4 = r10; \ 961 r4 += -16; \ 962 call %[bpf_dynptr_from_mem]; \ 963 r1 = r10; \ 964 r1 += -512; \ 965 r2 = 488; \ 966 r3 = r10; \ 967 r3 += -24; \ 968 r4 = 0; \ 969 r5 = 0; \ 970 call %[bpf_dynptr_read]; \ 971 r8 = 1; \ 972 if r0 != 0 goto sjmp2; \ 973 r8 = 0; \ 974 sjmp2: \ 975 r1 = r10; \ 976 r1 += -24; \ 977 r2 = 0; \ 978 call %[bpf_ringbuf_discard_dynptr]; " 979 : 980 : __imm(bpf_map_update_elem), 981 __imm(bpf_map_lookup_elem), 982 __imm(bpf_ringbuf_reserve_dynptr), 983 __imm(bpf_ringbuf_discard_dynptr), 984 __imm(bpf_dynptr_from_mem), 985 __imm(bpf_dynptr_read), 986 __imm_addr(ringbuf), 987 __imm_addr(array_map4) 988 : __clobber_all 989 ); 990 return 0; 991 } 992 993 /* Test that it is allowed to overwrite unreferenced dynptr. */ 994 SEC("?raw_tp") 995 __success 996 int dynptr_overwrite_unref(void *ctx) 997 { 998 struct bpf_dynptr ptr; 999 1000 if (get_map_val_dynptr(&ptr)) 1001 return 0; 1002 if (get_map_val_dynptr(&ptr)) 1003 return 0; 1004 if (get_map_val_dynptr(&ptr)) 1005 return 0; 1006 1007 return 0; 1008 } 1009 1010 /* Test that slices are invalidated on reinitializing a dynptr. */ 1011 SEC("?raw_tp") 1012 __failure __msg("invalid mem access 'scalar'") 1013 int dynptr_invalidate_slice_reinit(void *ctx) 1014 { 1015 struct bpf_dynptr ptr; 1016 __u8 *p; 1017 1018 if (get_map_val_dynptr(&ptr)) 1019 return 0; 1020 p = bpf_dynptr_data(&ptr, 0, 1); 1021 if (!p) 1022 return 0; 1023 if (get_map_val_dynptr(&ptr)) 1024 return 0; 1025 /* this should fail */ 1026 return *p; 1027 } 1028 1029 /* Invalidation of dynptr slices on destruction of dynptr should not miss 1030 * mem_or_null pointers. 1031 */ 1032 SEC("?raw_tp") 1033 __failure __msg("R{{[0-9]+}} type=scalar expected=percpu_ptr_") 1034 int dynptr_invalidate_slice_or_null(void *ctx) 1035 { 1036 struct bpf_dynptr ptr; 1037 __u8 *p; 1038 1039 if (get_map_val_dynptr(&ptr)) 1040 return 0; 1041 1042 p = bpf_dynptr_data(&ptr, 0, 1); 1043 *(__u8 *)&ptr = 0; 1044 /* this should fail */ 1045 bpf_this_cpu_ptr(p); 1046 return 0; 1047 } 1048 1049 /* Destruction of dynptr should also any slices obtained from it */ 1050 SEC("?raw_tp") 1051 __failure __msg("R{{[0-9]+}} invalid mem access 'scalar'") 1052 int dynptr_invalidate_slice_failure(void *ctx) 1053 { 1054 struct bpf_dynptr ptr1; 1055 struct bpf_dynptr ptr2; 1056 __u8 *p1, *p2; 1057 1058 if (get_map_val_dynptr(&ptr1)) 1059 return 0; 1060 if (get_map_val_dynptr(&ptr2)) 1061 return 0; 1062 1063 p1 = bpf_dynptr_data(&ptr1, 0, 1); 1064 if (!p1) 1065 return 0; 1066 p2 = bpf_dynptr_data(&ptr2, 0, 1); 1067 if (!p2) 1068 return 0; 1069 1070 *(__u8 *)&ptr1 = 0; 1071 /* this should fail */ 1072 return *p1; 1073 } 1074 1075 /* Invalidation of slices should be scoped and should not prevent dereferencing 1076 * slices of another dynptr after destroying unrelated dynptr 1077 */ 1078 SEC("?raw_tp") 1079 __success 1080 int dynptr_invalidate_slice_success(void *ctx) 1081 { 1082 struct bpf_dynptr ptr1; 1083 struct bpf_dynptr ptr2; 1084 __u8 *p1, *p2; 1085 1086 if (get_map_val_dynptr(&ptr1)) 1087 return 1; 1088 if (get_map_val_dynptr(&ptr2)) 1089 return 1; 1090 1091 p1 = bpf_dynptr_data(&ptr1, 0, 1); 1092 if (!p1) 1093 return 1; 1094 p2 = bpf_dynptr_data(&ptr2, 0, 1); 1095 if (!p2) 1096 return 1; 1097 1098 *(__u8 *)&ptr1 = 0; 1099 return *p2; 1100 } 1101 1102 /* Overwriting referenced dynptr should be rejected */ 1103 SEC("?raw_tp") 1104 __failure __msg("cannot overwrite referenced dynptr") 1105 int dynptr_overwrite_ref(void *ctx) 1106 { 1107 struct bpf_dynptr ptr; 1108 1109 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 1110 /* this should fail */ 1111 if (get_map_val_dynptr(&ptr)) 1112 bpf_ringbuf_discard_dynptr(&ptr, 0); 1113 return 0; 1114 } 1115 1116 /* Reject writes to dynptr slot from bpf_dynptr_read */ 1117 SEC("?raw_tp") 1118 __failure __msg("cannot overwrite referenced dynptr") 1119 int dynptr_read_into_slot(void *ctx) 1120 { 1121 union { 1122 struct { 1123 char _pad[48]; 1124 struct bpf_dynptr ptr; 1125 }; 1126 char buf[64]; 1127 } data; 1128 1129 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &data.ptr); 1130 /* this should fail */ 1131 bpf_dynptr_read(data.buf, sizeof(data.buf), &data.ptr, 0, 0); 1132 1133 return 0; 1134 } 1135 1136 /* bpf_dynptr_slice()s are read-only and cannot be written to */ 1137 SEC("?tc") 1138 __failure __msg("R{{[0-9]+}} cannot write into rdonly_mem") 1139 int skb_invalid_slice_write(struct __sk_buff *skb) 1140 { 1141 struct bpf_dynptr ptr; 1142 struct ethhdr *hdr; 1143 char buffer[sizeof(*hdr)] = {}; 1144 1145 bpf_dynptr_from_skb(skb, 0, &ptr); 1146 1147 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1148 if (!hdr) 1149 return SK_DROP; 1150 1151 /* this should fail */ 1152 hdr->h_proto = 1; 1153 1154 return SK_PASS; 1155 } 1156 1157 /* bpf_dynptr_slice()s are read-only and cannot be written to */ 1158 SEC("?tc") 1159 __failure __msg("R{{[0-9]+}} cannot write into rdonly_mem") 1160 int skb_meta_invalid_slice_write(struct __sk_buff *skb) 1161 { 1162 struct bpf_dynptr meta; 1163 __u8 *md; 1164 1165 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1166 1167 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md)); 1168 if (!md) 1169 return SK_DROP; 1170 1171 /* this should fail */ 1172 *md = 42; 1173 1174 return SK_PASS; 1175 } 1176 1177 /* The read-only data slice is invalidated whenever a helper changes packet data */ 1178 SEC("?tc") 1179 __failure __msg("invalid mem access 'scalar'") 1180 int skb_invalid_data_slice1(struct __sk_buff *skb) 1181 { 1182 struct bpf_dynptr ptr; 1183 struct ethhdr *hdr; 1184 char buffer[sizeof(*hdr)] = {}; 1185 1186 bpf_dynptr_from_skb(skb, 0, &ptr); 1187 1188 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1189 if (!hdr) 1190 return SK_DROP; 1191 1192 val = hdr->h_proto; 1193 1194 if (bpf_skb_pull_data(skb, skb->len)) 1195 return SK_DROP; 1196 1197 /* this should fail */ 1198 val = hdr->h_proto; 1199 1200 return SK_PASS; 1201 } 1202 1203 /* The read-write data slice is invalidated whenever a helper changes packet data */ 1204 SEC("?tc") 1205 __failure __msg("invalid mem access 'scalar'") 1206 int skb_invalid_data_slice2(struct __sk_buff *skb) 1207 { 1208 struct bpf_dynptr ptr; 1209 struct ethhdr *hdr; 1210 char buffer[sizeof(*hdr)] = {}; 1211 1212 bpf_dynptr_from_skb(skb, 0, &ptr); 1213 1214 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1215 if (!hdr) 1216 return SK_DROP; 1217 1218 hdr->h_proto = 123; 1219 1220 if (bpf_skb_pull_data(skb, skb->len)) 1221 return SK_DROP; 1222 1223 /* this should fail */ 1224 hdr->h_proto = 1; 1225 1226 return SK_PASS; 1227 } 1228 1229 /* The read-only data slice is invalidated whenever bpf_dynptr_write() is called */ 1230 SEC("?tc") 1231 __failure __msg("invalid mem access 'scalar'") 1232 int skb_invalid_data_slice3(struct __sk_buff *skb) 1233 { 1234 char write_data[64] = "hello there, world!!"; 1235 struct bpf_dynptr ptr; 1236 struct ethhdr *hdr; 1237 char buffer[sizeof(*hdr)] = {}; 1238 1239 bpf_dynptr_from_skb(skb, 0, &ptr); 1240 1241 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1242 if (!hdr) 1243 return SK_DROP; 1244 1245 val = hdr->h_proto; 1246 1247 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0); 1248 1249 /* this should fail */ 1250 val = hdr->h_proto; 1251 1252 return SK_PASS; 1253 } 1254 1255 /* The read-write data slice is invalidated whenever bpf_dynptr_write() is called */ 1256 SEC("?tc") 1257 __failure __msg("invalid mem access 'scalar'") 1258 int skb_invalid_data_slice4(struct __sk_buff *skb) 1259 { 1260 char write_data[64] = "hello there, world!!"; 1261 struct bpf_dynptr ptr; 1262 struct ethhdr *hdr; 1263 char buffer[sizeof(*hdr)] = {}; 1264 1265 bpf_dynptr_from_skb(skb, 0, &ptr); 1266 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1267 if (!hdr) 1268 return SK_DROP; 1269 1270 hdr->h_proto = 123; 1271 1272 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0); 1273 1274 /* this should fail */ 1275 hdr->h_proto = 1; 1276 1277 return SK_PASS; 1278 } 1279 1280 /* Read-only skb data slice is invalidated on write to skb metadata */ 1281 SEC("?tc") 1282 __failure __msg("invalid mem access 'scalar'") 1283 int ro_skb_slice_invalid_after_metadata_write(struct __sk_buff *skb) 1284 { 1285 struct bpf_dynptr data, meta; 1286 __u8 *d; 1287 1288 bpf_dynptr_from_skb(skb, 0, &data); 1289 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1290 1291 d = bpf_dynptr_slice(&data, 0, NULL, sizeof(*d)); 1292 if (!d) 1293 return SK_DROP; 1294 1295 bpf_dynptr_write(&meta, 0, "x", 1, 0); 1296 1297 /* this should fail */ 1298 val = *d; 1299 1300 return SK_PASS; 1301 } 1302 1303 /* Read-write skb data slice is invalidated on write to skb metadata */ 1304 SEC("?tc") 1305 __failure __msg("invalid mem access 'scalar'") 1306 int rw_skb_slice_invalid_after_metadata_write(struct __sk_buff *skb) 1307 { 1308 struct bpf_dynptr data, meta; 1309 __u8 *d; 1310 1311 bpf_dynptr_from_skb(skb, 0, &data); 1312 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1313 1314 d = bpf_dynptr_slice_rdwr(&data, 0, NULL, sizeof(*d)); 1315 if (!d) 1316 return SK_DROP; 1317 1318 bpf_dynptr_write(&meta, 0, "x", 1, 0); 1319 1320 /* this should fail */ 1321 *d = 42; 1322 1323 return SK_PASS; 1324 } 1325 1326 /* Read-only skb metadata slice is invalidated on write to skb data */ 1327 SEC("?tc") 1328 __failure __msg("invalid mem access 'scalar'") 1329 int ro_skb_meta_slice_invalid_after_payload_write(struct __sk_buff *skb) 1330 { 1331 struct bpf_dynptr data, meta; 1332 __u8 *md; 1333 1334 bpf_dynptr_from_skb(skb, 0, &data); 1335 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1336 1337 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md)); 1338 if (!md) 1339 return SK_DROP; 1340 1341 bpf_dynptr_write(&data, 0, "x", 1, 0); 1342 1343 /* this should fail */ 1344 val = *md; 1345 1346 return SK_PASS; 1347 } 1348 1349 /* Read-write skb metadata slice is invalidated on write to skb data slice */ 1350 SEC("?tc") 1351 __failure __msg("invalid mem access 'scalar'") 1352 int rw_skb_meta_slice_invalid_after_payload_write(struct __sk_buff *skb) 1353 { 1354 struct bpf_dynptr data, meta; 1355 __u8 *md; 1356 1357 bpf_dynptr_from_skb(skb, 0, &data); 1358 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1359 1360 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md)); 1361 if (!md) 1362 return SK_DROP; 1363 1364 bpf_dynptr_write(&data, 0, "x", 1, 0); 1365 1366 /* this should fail */ 1367 *md = 42; 1368 1369 return SK_PASS; 1370 } 1371 1372 /* Read-only skb metadata slice is invalidated whenever a helper changes packet data */ 1373 SEC("?tc") 1374 __failure __msg("invalid mem access 'scalar'") 1375 int ro_skb_meta_slice_invalid_after_payload_helper(struct __sk_buff *skb) 1376 { 1377 struct bpf_dynptr meta; 1378 __u8 *md; 1379 1380 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1381 1382 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md)); 1383 if (!md) 1384 return SK_DROP; 1385 1386 if (bpf_skb_pull_data(skb, skb->len)) 1387 return SK_DROP; 1388 1389 /* this should fail */ 1390 val = *md; 1391 1392 return SK_PASS; 1393 } 1394 1395 /* Read-write skb metadata slice is invalidated whenever a helper changes packet data */ 1396 SEC("?tc") 1397 __failure __msg("invalid mem access 'scalar'") 1398 int rw_skb_meta_slice_invalid_after_payload_helper(struct __sk_buff *skb) 1399 { 1400 struct bpf_dynptr meta; 1401 __u8 *md; 1402 1403 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1404 1405 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md)); 1406 if (!md) 1407 return SK_DROP; 1408 1409 if (bpf_skb_pull_data(skb, skb->len)) 1410 return SK_DROP; 1411 1412 /* this should fail */ 1413 *md = 42; 1414 1415 return SK_PASS; 1416 } 1417 1418 /* Read-only skb metadata slice is invalidated on write to skb metadata */ 1419 SEC("?tc") 1420 __failure __msg("invalid mem access 'scalar'") 1421 int ro_skb_meta_slice_invalid_after_metadata_write(struct __sk_buff *skb) 1422 { 1423 struct bpf_dynptr meta; 1424 __u8 *md; 1425 1426 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1427 1428 md = bpf_dynptr_slice(&meta, 0, NULL, sizeof(*md)); 1429 if (!md) 1430 return SK_DROP; 1431 1432 bpf_dynptr_write(&meta, 0, "x", 1, 0); 1433 1434 /* this should fail */ 1435 val = *md; 1436 1437 return SK_PASS; 1438 } 1439 1440 /* Read-write skb metadata slice is invalidated on write to skb metadata */ 1441 SEC("?tc") 1442 __failure __msg("invalid mem access 'scalar'") 1443 int rw_skb_meta_slice_invalid_after_metadata_write(struct __sk_buff *skb) 1444 { 1445 struct bpf_dynptr meta; 1446 __u8 *md; 1447 1448 bpf_dynptr_from_skb_meta(skb, 0, &meta); 1449 1450 md = bpf_dynptr_slice_rdwr(&meta, 0, NULL, sizeof(*md)); 1451 if (!md) 1452 return SK_DROP; 1453 1454 bpf_dynptr_write(&meta, 0, "x", 1, 0); 1455 1456 /* this should fail */ 1457 *md = 42; 1458 1459 return SK_PASS; 1460 } 1461 1462 /* The read-only data slice is invalidated whenever a helper changes packet data */ 1463 SEC("?xdp") 1464 __failure __msg("invalid mem access 'scalar'") 1465 int xdp_invalid_data_slice1(struct xdp_md *xdp) 1466 { 1467 struct bpf_dynptr ptr; 1468 struct ethhdr *hdr; 1469 char buffer[sizeof(*hdr)] = {}; 1470 1471 bpf_dynptr_from_xdp(xdp, 0, &ptr); 1472 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1473 if (!hdr) 1474 return SK_DROP; 1475 1476 val = hdr->h_proto; 1477 1478 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr))) 1479 return XDP_DROP; 1480 1481 /* this should fail */ 1482 val = hdr->h_proto; 1483 1484 return XDP_PASS; 1485 } 1486 1487 /* The read-write data slice is invalidated whenever a helper changes packet data */ 1488 SEC("?xdp") 1489 __failure __msg("invalid mem access 'scalar'") 1490 int xdp_invalid_data_slice2(struct xdp_md *xdp) 1491 { 1492 struct bpf_dynptr ptr; 1493 struct ethhdr *hdr; 1494 char buffer[sizeof(*hdr)] = {}; 1495 1496 bpf_dynptr_from_xdp(xdp, 0, &ptr); 1497 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1498 if (!hdr) 1499 return SK_DROP; 1500 1501 hdr->h_proto = 9; 1502 1503 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr))) 1504 return XDP_DROP; 1505 1506 /* this should fail */ 1507 hdr->h_proto = 1; 1508 1509 return XDP_PASS; 1510 } 1511 1512 /* Only supported prog type can create skb-type dynptrs */ 1513 SEC("?xdp") 1514 __failure __msg("calling kernel function bpf_dynptr_from_skb is not allowed") 1515 int skb_invalid_ctx(void *ctx) 1516 { 1517 struct bpf_dynptr ptr; 1518 1519 /* this should fail */ 1520 bpf_dynptr_from_skb(ctx, 0, &ptr); 1521 1522 return 0; 1523 } 1524 1525 /* Only supported prog type can create skb_meta-type dynptrs */ 1526 SEC("?raw_tp") 1527 __failure __msg("calling kernel function bpf_dynptr_from_skb_meta is not allowed") 1528 int skb_meta_invalid_ctx(void *ctx) 1529 { 1530 struct bpf_dynptr meta; 1531 1532 /* this should fail */ 1533 bpf_dynptr_from_skb_meta(ctx, 0, &meta); 1534 1535 return 0; 1536 } 1537 1538 SEC("fentry/skb_tx_error") 1539 __failure __msg("must be referenced or trusted") 1540 int BPF_PROG(skb_invalid_ctx_fentry, void *skb) 1541 { 1542 struct bpf_dynptr ptr; 1543 1544 /* this should fail */ 1545 bpf_dynptr_from_skb(skb, 0, &ptr); 1546 1547 return 0; 1548 } 1549 1550 SEC("fexit/skb_tx_error") 1551 __failure __msg("must be referenced or trusted") 1552 int BPF_PROG(skb_invalid_ctx_fexit, void *skb) 1553 { 1554 struct bpf_dynptr ptr; 1555 1556 /* this should fail */ 1557 bpf_dynptr_from_skb(skb, 0, &ptr); 1558 1559 return 0; 1560 } 1561 1562 /* Reject writes to dynptr slot for uninit arg */ 1563 SEC("?raw_tp") 1564 __failure __msg("cannot overwrite referenced dynptr") 1565 int uninit_write_into_slot(void *ctx) 1566 { 1567 struct { 1568 char buf[64]; 1569 struct bpf_dynptr ptr; 1570 } data; 1571 1572 bpf_ringbuf_reserve_dynptr(&ringbuf, 80, 0, &data.ptr); 1573 /* this should fail */ 1574 bpf_get_current_comm(data.buf, 80); 1575 1576 return 0; 1577 } 1578 1579 /* Only supported prog type can create xdp-type dynptrs */ 1580 SEC("?raw_tp") 1581 __failure __msg("calling kernel function bpf_dynptr_from_xdp is not allowed") 1582 int xdp_invalid_ctx(void *ctx) 1583 { 1584 struct bpf_dynptr ptr; 1585 1586 /* this should fail */ 1587 bpf_dynptr_from_xdp(ctx, 0, &ptr); 1588 1589 return 0; 1590 } 1591 1592 __u32 hdr_size = sizeof(struct ethhdr); 1593 /* Can't pass in variable-sized len to bpf_dynptr_slice */ 1594 SEC("?tc") 1595 __failure __msg("must be a known constant") 1596 __msg("requires this memory size to be a verifier-known constant") 1597 int dynptr_slice_var_len1(struct __sk_buff *skb) 1598 { 1599 struct bpf_dynptr ptr; 1600 struct ethhdr *hdr; 1601 char buffer[sizeof(*hdr)] = {}; 1602 1603 bpf_dynptr_from_skb(skb, 0, &ptr); 1604 1605 /* this should fail */ 1606 hdr = bpf_dynptr_slice(&ptr, 0, buffer, hdr_size); 1607 if (!hdr) 1608 return SK_DROP; 1609 1610 return SK_PASS; 1611 } 1612 1613 /* Can't pass in variable-sized len to bpf_dynptr_slice */ 1614 SEC("?tc") 1615 __failure __msg("must be a known constant") 1616 __msg("requires this memory size to be a verifier-known constant") 1617 int dynptr_slice_var_len2(struct __sk_buff *skb) 1618 { 1619 char buffer[sizeof(struct ethhdr)] = {}; 1620 struct bpf_dynptr ptr; 1621 struct ethhdr *hdr; 1622 1623 bpf_dynptr_from_skb(skb, 0, &ptr); 1624 1625 if (hdr_size <= sizeof(buffer)) { 1626 /* this should fail */ 1627 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, hdr_size); 1628 if (!hdr) 1629 return SK_DROP; 1630 hdr->h_proto = 12; 1631 } 1632 1633 return SK_PASS; 1634 } 1635 1636 static int callback(__u32 index, void *data) 1637 { 1638 *(__u32 *)data = 123; 1639 1640 return 0; 1641 } 1642 1643 /* A commuted add should preserve the parent id of a dynptr data slice. */ 1644 SEC("?raw_tp") 1645 __failure __msg("invalid mem access 'scalar'") 1646 int dynptr_slice_commuted_invalidate(void *ctx) 1647 { 1648 struct bpf_dynptr ptr; 1649 __u32 *slice, *derived; 1650 1651 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(__u32), 0, &ptr); 1652 1653 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32)); 1654 if (!slice) 1655 goto done; 1656 1657 asm volatile ("%[dst] = 0;" 1658 "%[dst] += %[src];" 1659 "%[src] = 0;" 1660 : [dst]"=&r"(derived), [src]"+r"(slice) 1661 : 1662 : "memory"); 1663 1664 bpf_ringbuf_discard_dynptr(&ptr, 0); 1665 val = *derived; 1666 return 0; 1667 1668 done: 1669 bpf_ringbuf_discard_dynptr(&ptr, 0); 1670 return 0; 1671 } 1672 1673 /* If the dynptr is written into in a callback function, its data 1674 * slices should be invalidated as well. 1675 */ 1676 SEC("?raw_tp") 1677 __failure __msg("invalid mem access 'scalar'") 1678 int invalid_data_slices(void *ctx) 1679 { 1680 struct bpf_dynptr ptr; 1681 __u32 *slice; 1682 1683 if (get_map_val_dynptr(&ptr)) 1684 return 0; 1685 1686 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32)); 1687 if (!slice) 1688 return 0; 1689 1690 bpf_loop(10, callback, &ptr, 0); 1691 1692 /* this should fail */ 1693 *slice = 1; 1694 1695 return 0; 1696 } 1697 1698 /* Program types that don't allow writes to packet data should fail if 1699 * bpf_dynptr_slice_rdwr is called 1700 */ 1701 SEC("cgroup_skb/ingress") 1702 __failure __msg("the prog does not allow writes to packet data") 1703 int invalid_slice_rdwr_rdonly(struct __sk_buff *skb) 1704 { 1705 char buffer[sizeof(struct ethhdr)] = {}; 1706 struct bpf_dynptr ptr; 1707 struct ethhdr *hdr; 1708 1709 bpf_dynptr_from_skb(skb, 0, &ptr); 1710 1711 /* this should fail since cgroup_skb doesn't allow 1712 * changing packet data 1713 */ 1714 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1715 __sink(hdr); 1716 1717 return 0; 1718 } 1719 1720 /* bpf_dynptr_adjust can only be called on initialized dynptrs */ 1721 SEC("?raw_tp") 1722 __failure __msg("Expected an initialized dynptr as R1") 1723 int dynptr_adjust_invalid(void *ctx) 1724 { 1725 struct bpf_dynptr ptr = {}; 1726 1727 /* this should fail */ 1728 bpf_dynptr_adjust(&ptr, 1, 2); 1729 1730 return 0; 1731 } 1732 1733 /* bpf_dynptr_is_null can only be called on initialized dynptrs */ 1734 SEC("?raw_tp") 1735 __failure __msg("Expected an initialized dynptr as R1") 1736 int dynptr_is_null_invalid(void *ctx) 1737 { 1738 struct bpf_dynptr ptr = {}; 1739 1740 /* this should fail */ 1741 bpf_dynptr_is_null(&ptr); 1742 1743 return 0; 1744 } 1745 1746 /* bpf_dynptr_is_rdonly can only be called on initialized dynptrs */ 1747 SEC("?raw_tp") 1748 __failure __msg("Expected an initialized dynptr as R1") 1749 int dynptr_is_rdonly_invalid(void *ctx) 1750 { 1751 struct bpf_dynptr ptr = {}; 1752 1753 /* this should fail */ 1754 bpf_dynptr_is_rdonly(&ptr); 1755 1756 return 0; 1757 } 1758 1759 /* bpf_dynptr_size can only be called on initialized dynptrs */ 1760 SEC("?raw_tp") 1761 __failure __msg("Expected an initialized dynptr as R1") 1762 int dynptr_size_invalid(void *ctx) 1763 { 1764 struct bpf_dynptr ptr = {}; 1765 1766 /* this should fail */ 1767 bpf_dynptr_size(&ptr); 1768 1769 return 0; 1770 } 1771 1772 /* Only initialized dynptrs can be cloned */ 1773 SEC("?raw_tp") 1774 __failure __msg("Expected an initialized dynptr as R1") 1775 int clone_invalid1(void *ctx) 1776 { 1777 struct bpf_dynptr ptr1 = {}; 1778 struct bpf_dynptr ptr2; 1779 1780 /* this should fail */ 1781 bpf_dynptr_clone(&ptr1, &ptr2); 1782 1783 return 0; 1784 } 1785 1786 /* Can't overwrite an existing dynptr when cloning */ 1787 SEC("?xdp") 1788 __failure __msg("cannot overwrite referenced dynptr") 1789 int clone_invalid2(struct xdp_md *xdp) 1790 { 1791 struct bpf_dynptr ptr1; 1792 struct bpf_dynptr clone; 1793 1794 bpf_dynptr_from_xdp(xdp, 0, &ptr1); 1795 1796 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &clone); 1797 1798 /* this should fail */ 1799 bpf_dynptr_clone(&ptr1, &clone); 1800 1801 bpf_ringbuf_submit_dynptr(&clone, 0); 1802 1803 return 0; 1804 } 1805 1806 /* Invalidating a dynptr should invalidate its clones */ 1807 SEC("?raw_tp") 1808 __failure __msg("Expected an initialized dynptr as R3") 1809 int clone_invalidate1(void *ctx) 1810 { 1811 struct bpf_dynptr clone; 1812 struct bpf_dynptr ptr; 1813 char read_data[64]; 1814 1815 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1816 1817 bpf_dynptr_clone(&ptr, &clone); 1818 1819 bpf_ringbuf_submit_dynptr(&ptr, 0); 1820 1821 /* this should fail */ 1822 bpf_dynptr_read(read_data, sizeof(read_data), &clone, 0, 0); 1823 1824 return 0; 1825 } 1826 1827 /* Invalidating a dynptr should invalidate its parent */ 1828 SEC("?raw_tp") 1829 __failure __msg("Expected an initialized dynptr as R3") 1830 int clone_invalidate2(void *ctx) 1831 { 1832 struct bpf_dynptr ptr; 1833 struct bpf_dynptr clone; 1834 char read_data[64]; 1835 1836 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1837 1838 bpf_dynptr_clone(&ptr, &clone); 1839 1840 bpf_ringbuf_submit_dynptr(&clone, 0); 1841 1842 /* this should fail */ 1843 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 1844 1845 return 0; 1846 } 1847 1848 /* Invalidating a dynptr should invalidate its siblings */ 1849 SEC("?raw_tp") 1850 __failure __msg("Expected an initialized dynptr as R3") 1851 int clone_invalidate3(void *ctx) 1852 { 1853 struct bpf_dynptr ptr; 1854 struct bpf_dynptr clone1; 1855 struct bpf_dynptr clone2; 1856 char read_data[64]; 1857 1858 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1859 1860 bpf_dynptr_clone(&ptr, &clone1); 1861 1862 bpf_dynptr_clone(&ptr, &clone2); 1863 1864 bpf_ringbuf_submit_dynptr(&clone2, 0); 1865 1866 /* this should fail */ 1867 bpf_dynptr_read(read_data, sizeof(read_data), &clone1, 0, 0); 1868 1869 return 0; 1870 } 1871 1872 /* Invalidating a dynptr should invalidate any data slices 1873 * of its clones 1874 */ 1875 SEC("?raw_tp") 1876 __failure __msg("invalid mem access 'scalar'") 1877 int clone_invalidate4(void *ctx) 1878 { 1879 struct bpf_dynptr ptr; 1880 struct bpf_dynptr clone; 1881 int *data; 1882 1883 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1884 1885 bpf_dynptr_clone(&ptr, &clone); 1886 data = bpf_dynptr_data(&clone, 0, sizeof(val)); 1887 if (!data) 1888 return 0; 1889 1890 bpf_ringbuf_submit_dynptr(&ptr, 0); 1891 1892 /* this should fail */ 1893 *data = 123; 1894 1895 return 0; 1896 } 1897 1898 static __noinline void clone_slice_in_subprog(struct bpf_dynptr *ptr, int **data) 1899 { 1900 struct bpf_dynptr clone; 1901 1902 bpf_dynptr_clone(ptr, &clone); 1903 *data = bpf_dynptr_data(&clone, 0, sizeof(val)); 1904 } 1905 1906 static __noinline void caller_slice_in_subprog(struct bpf_dynptr *ptr, int **data) 1907 { 1908 struct bpf_dynptr clone; 1909 1910 *data = bpf_dynptr_data(ptr, 0, sizeof(val)); 1911 bpf_dynptr_clone(ptr, &clone); 1912 } 1913 1914 static __noinline void reserve_dynptr_in_subprog(void) 1915 { 1916 struct bpf_dynptr ptr; 1917 1918 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1919 } 1920 1921 /* A subprogram cannot lose the last dynptr that can release a resource. */ 1922 SEC("?raw_tp") 1923 __failure __msg("cannot overwrite referenced dynptr") 1924 int referenced_dynptr_lost_on_subprog_return(void *ctx) 1925 { 1926 reserve_dynptr_in_subprog(); 1927 1928 return 0; 1929 } 1930 1931 /* 1932 * Destroying a callee-local clone on return must not invalidate a slice whose 1933 * source dynptr belongs to the caller. 1934 */ 1935 SEC("?raw_tp") 1936 __success 1937 int caller_dynptr_slice_across_subprog_valid(void *ctx) 1938 { 1939 struct bpf_dynptr ptr; 1940 int *data = NULL; 1941 1942 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1943 caller_slice_in_subprog(&ptr, &data); 1944 if (data) 1945 *data = 123; 1946 bpf_ringbuf_submit_dynptr(&ptr, 0); 1947 1948 return 0; 1949 } 1950 1951 /* 1952 * A slice derived from a callee-local clone is invalid after the subprogram 1953 * returns. 1954 */ 1955 SEC("?raw_tp") 1956 __failure __msg("invalid mem access 'scalar'") 1957 int callee_dynptr_slice_invalid_after_return(void *ctx) 1958 { 1959 struct bpf_dynptr ptr; 1960 int *data = NULL; 1961 1962 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1963 clone_slice_in_subprog(&ptr, &data); 1964 if (data) 1965 /* this should fail */ 1966 *data = 123; 1967 bpf_ringbuf_submit_dynptr(&ptr, 0); 1968 1969 return 0; 1970 } 1971 1972 /* 1973 * A slice from a caller-owned dynptr survives the subprogram return, but 1974 * releasing the shared reservation must invalidate it. 1975 */ 1976 SEC("?raw_tp") 1977 __failure __msg("invalid mem access 'scalar'") 1978 int caller_dynptr_slice_release_after_subprog_invalid(void *ctx) 1979 { 1980 struct bpf_dynptr ptr; 1981 int *data = NULL; 1982 1983 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1984 caller_slice_in_subprog(&ptr, &data); 1985 bpf_ringbuf_submit_dynptr(&ptr, 0); 1986 if (data) 1987 /* this should fail */ 1988 *data = 123; 1989 1990 return 0; 1991 } 1992 1993 /* Invalidating a dynptr should invalidate any data slices 1994 * of its parent 1995 */ 1996 SEC("?raw_tp") 1997 __failure __msg("invalid mem access 'scalar'") 1998 int clone_invalidate5(void *ctx) 1999 { 2000 struct bpf_dynptr ptr; 2001 struct bpf_dynptr clone; 2002 int *data; 2003 2004 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 2005 data = bpf_dynptr_data(&ptr, 0, sizeof(val)); 2006 if (!data) 2007 return 0; 2008 2009 bpf_dynptr_clone(&ptr, &clone); 2010 2011 bpf_ringbuf_submit_dynptr(&clone, 0); 2012 2013 /* this should fail */ 2014 *data = 123; 2015 2016 return 0; 2017 } 2018 2019 /* Invalidating a dynptr should invalidate any data slices 2020 * of its sibling 2021 */ 2022 SEC("?raw_tp") 2023 __failure __msg("invalid mem access 'scalar'") 2024 int clone_invalidate6(void *ctx) 2025 { 2026 struct bpf_dynptr ptr; 2027 struct bpf_dynptr clone1; 2028 struct bpf_dynptr clone2; 2029 int *data; 2030 2031 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 2032 2033 bpf_dynptr_clone(&ptr, &clone1); 2034 2035 bpf_dynptr_clone(&ptr, &clone2); 2036 2037 data = bpf_dynptr_data(&clone1, 0, sizeof(val)); 2038 if (!data) 2039 return 0; 2040 2041 bpf_ringbuf_submit_dynptr(&clone2, 0); 2042 2043 /* this should fail */ 2044 *data = 123; 2045 2046 return 0; 2047 } 2048 2049 /* A skb clone's data slices should be invalid anytime packet data changes */ 2050 SEC("?tc") 2051 __failure __msg("invalid mem access 'scalar'") 2052 int clone_skb_packet_data(struct __sk_buff *skb) 2053 { 2054 char buffer[sizeof(__u32)] = {}; 2055 struct bpf_dynptr clone; 2056 struct bpf_dynptr ptr; 2057 __u32 *data; 2058 2059 bpf_dynptr_from_skb(skb, 0, &ptr); 2060 2061 bpf_dynptr_clone(&ptr, &clone); 2062 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer)); 2063 if (!data) 2064 return XDP_DROP; 2065 2066 if (bpf_skb_pull_data(skb, skb->len)) 2067 return SK_DROP; 2068 2069 /* this should fail */ 2070 *data = 123; 2071 2072 return 0; 2073 } 2074 2075 /* A skb clone's metadata slice becomes invalid anytime packet data changes */ 2076 SEC("?tc") 2077 __failure __msg("invalid mem access 'scalar'") 2078 int clone_skb_packet_meta(struct __sk_buff *skb) 2079 { 2080 struct bpf_dynptr clone, meta; 2081 __u8 *md; 2082 2083 bpf_dynptr_from_skb_meta(skb, 0, &meta); 2084 bpf_dynptr_clone(&meta, &clone); 2085 md = bpf_dynptr_slice_rdwr(&clone, 0, NULL, sizeof(*md)); 2086 if (!md) 2087 return SK_DROP; 2088 2089 if (bpf_skb_pull_data(skb, skb->len)) 2090 return SK_DROP; 2091 2092 /* this should fail */ 2093 *md = 42; 2094 2095 return 0; 2096 } 2097 2098 /* A xdp clone's data slices should be invalid anytime packet data changes */ 2099 SEC("?xdp") 2100 __failure __msg("invalid mem access 'scalar'") 2101 int clone_xdp_packet_data(struct xdp_md *xdp) 2102 { 2103 char buffer[sizeof(__u32)] = {}; 2104 struct bpf_dynptr clone; 2105 struct bpf_dynptr ptr; 2106 struct ethhdr *hdr; 2107 __u32 *data; 2108 2109 bpf_dynptr_from_xdp(xdp, 0, &ptr); 2110 2111 bpf_dynptr_clone(&ptr, &clone); 2112 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer)); 2113 if (!data) 2114 return XDP_DROP; 2115 2116 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr))) 2117 return XDP_DROP; 2118 2119 /* this should fail */ 2120 *data = 123; 2121 2122 return 0; 2123 } 2124 2125 /* Buffers that are provided must be sufficiently long */ 2126 SEC("?cgroup_skb/egress") 2127 __failure __msg("memory, len pair leads to invalid memory access") 2128 int test_dynptr_skb_small_buff(struct __sk_buff *skb) 2129 { 2130 struct bpf_dynptr ptr; 2131 char buffer[8] = {}; 2132 __u64 *data; 2133 2134 if (bpf_dynptr_from_skb(skb, 0, &ptr)) { 2135 err = 1; 2136 return 1; 2137 } 2138 2139 /* This may return NULL. SKB may require a buffer */ 2140 data = bpf_dynptr_slice(&ptr, 0, buffer, 9); 2141 2142 return !!data; 2143 } 2144 2145 __noinline long global_call_bpf_dynptr(const struct bpf_dynptr *dynptr) 2146 { 2147 long ret = 0; 2148 /* Avoid leaving this global function empty to avoid having the compiler 2149 * optimize away the call to this global function. 2150 */ 2151 __sink(dynptr); 2152 __sink(ret); 2153 return ret; 2154 } 2155 2156 SEC("?raw_tp") 2157 __failure __msg("R1 type=trusted_ptr_ expected=fp, dynptr_ptr") 2158 int test_dynptr_reg_type(void *ctx) 2159 { 2160 struct task_struct *current = bpf_get_current_task_btf(); 2161 /* R1 holds a PTR_TO_BTF_ID, which cannot be passed to a function 2162 * accepting ARG_PTR_TO_DYNPTR | MEM_RDONLY. 2163 */ 2164 global_call_bpf_dynptr((const struct bpf_dynptr *)current); 2165 return 0; 2166 } 2167 2168 /* Overwriting a referenced dynptr is allowed if a clone still holds the ref */ 2169 SEC("?raw_tp") 2170 __success 2171 int dynptr_overwrite_ref_with_clone(void *ctx) 2172 { 2173 struct bpf_dynptr ptr, clone; 2174 2175 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 2176 2177 bpf_dynptr_clone(&ptr, &clone); 2178 2179 /* Overwrite the original - clone still holds the ref */ 2180 *(volatile __u8 *)&ptr = 0; 2181 2182 bpf_ringbuf_discard_dynptr(&clone, 0); 2183 2184 return 0; 2185 } 2186 2187 /* Overwriting the last referenced dynptr should still be rejected */ 2188 SEC("?raw_tp") 2189 __failure __msg("cannot overwrite referenced dynptr") 2190 int dynptr_overwrite_ref_last_clone(void *ctx) 2191 { 2192 struct bpf_dynptr ptr, clone; 2193 2194 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 2195 2196 bpf_dynptr_clone(&ptr, &clone); 2197 2198 /* Overwrite the original - clone still holds the ref, OK */ 2199 *(volatile __u8 *)&ptr = 0; 2200 2201 /* Overwrite the last holder - this should fail */ 2202 *(volatile __u8 *)&clone = 0; 2203 2204 return 0; 2205 } 2206 2207 /* Overwriting a clone should be allowed if the original still holds the ref */ 2208 SEC("?raw_tp") 2209 __success 2210 int dynptr_overwrite_clone_with_original(void *ctx) 2211 { 2212 struct bpf_dynptr ptr, clone; 2213 2214 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 2215 2216 bpf_dynptr_clone(&ptr, &clone); 2217 2218 /* Overwrite the clone - original still holds the ref */ 2219 *(volatile __u8 *)&clone = 0; 2220 2221 bpf_ringbuf_discard_dynptr(&ptr, 0); 2222 2223 return 0; 2224 } 2225 2226 /* Data slices from the destroyed dynptr should be invalidated */ 2227 SEC("?raw_tp") 2228 __failure __msg("invalid mem access 'scalar'") 2229 int dynptr_overwrite_ref_invalidate_slice(void *ctx) 2230 { 2231 struct bpf_dynptr ptr, clone; 2232 int *data; 2233 2234 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 2235 2236 data = bpf_dynptr_data(&ptr, 0, sizeof(val)); 2237 if (!data) 2238 return 0; 2239 2240 bpf_dynptr_clone(&ptr, &clone); 2241 2242 /* Overwrite the original - clone holds the ref */ 2243 *(volatile __u8 *)&ptr = 0; 2244 2245 /* data was from the original dynptr, should be invalid now */ 2246 *data = 123; 2247 2248 return 0; 2249 } 2250 2251 /* 2252 * Data slices from a dynptr clone should remain valid after 2253 * overwriting the original dynptr 2254 */ 2255 SEC("?raw_tp") 2256 __success 2257 int dynptr_overwrite_ref_clone_slice_valid(void *ctx) 2258 { 2259 struct bpf_dynptr ptr, clone; 2260 int *data; 2261 2262 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 2263 2264 bpf_dynptr_clone(&ptr, &clone); 2265 2266 data = bpf_dynptr_data(&clone, 0, sizeof(val)); 2267 if (!data) { 2268 bpf_ringbuf_discard_dynptr(&clone, 0); 2269 return 0; 2270 } 2271 2272 /* Overwrite the original - clone holds the ref */ 2273 *(volatile __u8 *)&ptr = 0; 2274 2275 /* data is from the clone, should still be valid */ 2276 *data = 123; 2277 2278 bpf_ringbuf_discard_dynptr(&clone, 0); 2279 2280 return 0; 2281 } 2282