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 <linux/if_ether.h> 10 #include "bpf_misc.h" 11 #include "bpf_kfuncs.h" 12 13 char _license[] SEC("license") = "GPL"; 14 15 struct test_info { 16 int x; 17 struct bpf_dynptr ptr; 18 }; 19 20 struct { 21 __uint(type, BPF_MAP_TYPE_ARRAY); 22 __uint(max_entries, 1); 23 __type(key, __u32); 24 __type(value, struct bpf_dynptr); 25 } array_map1 SEC(".maps"); 26 27 struct { 28 __uint(type, BPF_MAP_TYPE_ARRAY); 29 __uint(max_entries, 1); 30 __type(key, __u32); 31 __type(value, struct test_info); 32 } array_map2 SEC(".maps"); 33 34 struct { 35 __uint(type, BPF_MAP_TYPE_ARRAY); 36 __uint(max_entries, 1); 37 __type(key, __u32); 38 __type(value, __u32); 39 } array_map3 SEC(".maps"); 40 41 struct { 42 __uint(type, BPF_MAP_TYPE_ARRAY); 43 __uint(max_entries, 1); 44 __type(key, __u32); 45 __type(value, __u64); 46 } array_map4 SEC(".maps"); 47 48 struct sample { 49 int pid; 50 long value; 51 char comm[16]; 52 }; 53 54 struct { 55 __uint(type, BPF_MAP_TYPE_RINGBUF); 56 __uint(max_entries, 4096); 57 } ringbuf SEC(".maps"); 58 59 int err, val; 60 61 static int get_map_val_dynptr(struct bpf_dynptr *ptr) 62 { 63 __u32 key = 0, *map_val; 64 65 bpf_map_update_elem(&array_map3, &key, &val, 0); 66 67 map_val = bpf_map_lookup_elem(&array_map3, &key); 68 if (!map_val) 69 return -ENOENT; 70 71 bpf_dynptr_from_mem(map_val, sizeof(*map_val), 0, ptr); 72 73 return 0; 74 } 75 76 /* Every bpf_ringbuf_reserve_dynptr call must have a corresponding 77 * bpf_ringbuf_submit/discard_dynptr call 78 */ 79 SEC("?raw_tp") 80 __failure __msg("Unreleased reference id=2") 81 int ringbuf_missing_release1(void *ctx) 82 { 83 struct bpf_dynptr ptr = {}; 84 85 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 86 87 /* missing a call to bpf_ringbuf_discard/submit_dynptr */ 88 89 return 0; 90 } 91 92 SEC("?raw_tp") 93 __failure __msg("Unreleased reference id=4") 94 int ringbuf_missing_release2(void *ctx) 95 { 96 struct bpf_dynptr ptr1, ptr2; 97 struct sample *sample; 98 99 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr1); 100 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2); 101 102 sample = bpf_dynptr_data(&ptr1, 0, sizeof(*sample)); 103 if (!sample) { 104 bpf_ringbuf_discard_dynptr(&ptr1, 0); 105 bpf_ringbuf_discard_dynptr(&ptr2, 0); 106 return 0; 107 } 108 109 bpf_ringbuf_submit_dynptr(&ptr1, 0); 110 111 /* missing a call to bpf_ringbuf_discard/submit_dynptr on ptr2 */ 112 113 return 0; 114 } 115 116 static int missing_release_callback_fn(__u32 index, void *data) 117 { 118 struct bpf_dynptr ptr; 119 120 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 121 122 /* missing a call to bpf_ringbuf_discard/submit_dynptr */ 123 124 return 0; 125 } 126 127 /* Any dynptr initialized within a callback must have bpf_dynptr_put called */ 128 SEC("?raw_tp") 129 __failure __msg("Unreleased reference id") 130 int ringbuf_missing_release_callback(void *ctx) 131 { 132 bpf_loop(10, missing_release_callback_fn, NULL, 0); 133 return 0; 134 } 135 136 /* Can't call bpf_ringbuf_submit/discard_dynptr on a non-initialized dynptr */ 137 SEC("?raw_tp") 138 __failure __msg("arg 1 is an unacquired reference") 139 int ringbuf_release_uninit_dynptr(void *ctx) 140 { 141 struct bpf_dynptr ptr; 142 143 /* this should fail */ 144 bpf_ringbuf_submit_dynptr(&ptr, 0); 145 146 return 0; 147 } 148 149 /* A dynptr can't be used after it has been invalidated */ 150 SEC("?raw_tp") 151 __failure __msg("Expected an initialized dynptr as arg #3") 152 int use_after_invalid(void *ctx) 153 { 154 struct bpf_dynptr ptr; 155 char read_data[64]; 156 157 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(read_data), 0, &ptr); 158 159 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 160 161 bpf_ringbuf_submit_dynptr(&ptr, 0); 162 163 /* this should fail */ 164 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 165 166 return 0; 167 } 168 169 /* Can't call non-dynptr ringbuf APIs on a dynptr ringbuf sample */ 170 SEC("?raw_tp") 171 __failure __msg("type=mem expected=ringbuf_mem") 172 int ringbuf_invalid_api(void *ctx) 173 { 174 struct bpf_dynptr ptr; 175 struct sample *sample; 176 177 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr); 178 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample)); 179 if (!sample) 180 goto done; 181 182 sample->pid = 123; 183 184 /* invalid API use. need to use dynptr API to submit/discard */ 185 bpf_ringbuf_submit(sample, 0); 186 187 done: 188 bpf_ringbuf_discard_dynptr(&ptr, 0); 189 return 0; 190 } 191 192 /* Can't add a dynptr to a map */ 193 SEC("?raw_tp") 194 __failure __msg("invalid indirect read from stack") 195 int add_dynptr_to_map1(void *ctx) 196 { 197 struct bpf_dynptr ptr; 198 int key = 0; 199 200 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 201 202 /* this should fail */ 203 bpf_map_update_elem(&array_map1, &key, &ptr, 0); 204 205 bpf_ringbuf_submit_dynptr(&ptr, 0); 206 207 return 0; 208 } 209 210 /* Can't add a struct with an embedded dynptr to a map */ 211 SEC("?raw_tp") 212 __failure __msg("invalid indirect read from stack") 213 int add_dynptr_to_map2(void *ctx) 214 { 215 struct test_info x; 216 int key = 0; 217 218 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &x.ptr); 219 220 /* this should fail */ 221 bpf_map_update_elem(&array_map2, &key, &x, 0); 222 223 bpf_ringbuf_submit_dynptr(&x.ptr, 0); 224 225 return 0; 226 } 227 228 /* A data slice can't be accessed out of bounds */ 229 SEC("?raw_tp") 230 __failure __msg("value is outside of the allowed memory range") 231 int data_slice_out_of_bounds_ringbuf(void *ctx) 232 { 233 struct bpf_dynptr ptr; 234 void *data; 235 236 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr); 237 238 data = bpf_dynptr_data(&ptr, 0, 8); 239 if (!data) 240 goto done; 241 242 /* can't index out of bounds of the data slice */ 243 val = *((char *)data + 8); 244 245 done: 246 bpf_ringbuf_submit_dynptr(&ptr, 0); 247 return 0; 248 } 249 250 /* A data slice can't be accessed out of bounds */ 251 SEC("?tc") 252 __failure __msg("value is outside of the allowed memory range") 253 int data_slice_out_of_bounds_skb(struct __sk_buff *skb) 254 { 255 struct bpf_dynptr ptr; 256 struct ethhdr *hdr; 257 char buffer[sizeof(*hdr)] = {}; 258 259 bpf_dynptr_from_skb(skb, 0, &ptr); 260 261 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 262 if (!hdr) 263 return SK_DROP; 264 265 /* this should fail */ 266 *(__u8*)(hdr + 1) = 1; 267 268 return SK_PASS; 269 } 270 271 SEC("?raw_tp") 272 __failure __msg("value is outside of the allowed memory range") 273 int data_slice_out_of_bounds_map_value(void *ctx) 274 { 275 __u32 map_val; 276 struct bpf_dynptr ptr; 277 void *data; 278 279 get_map_val_dynptr(&ptr); 280 281 data = bpf_dynptr_data(&ptr, 0, sizeof(map_val)); 282 if (!data) 283 return 0; 284 285 /* can't index out of bounds of the data slice */ 286 val = *((char *)data + (sizeof(map_val) + 1)); 287 288 return 0; 289 } 290 291 /* A data slice can't be used after it has been released */ 292 SEC("?raw_tp") 293 __failure __msg("invalid mem access 'scalar'") 294 int data_slice_use_after_release1(void *ctx) 295 { 296 struct bpf_dynptr ptr; 297 struct sample *sample; 298 299 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr); 300 sample = bpf_dynptr_data(&ptr, 0, sizeof(*sample)); 301 if (!sample) 302 goto done; 303 304 sample->pid = 123; 305 306 bpf_ringbuf_submit_dynptr(&ptr, 0); 307 308 /* this should fail */ 309 val = sample->pid; 310 311 return 0; 312 313 done: 314 bpf_ringbuf_discard_dynptr(&ptr, 0); 315 return 0; 316 } 317 318 /* A data slice can't be used after it has been released. 319 * 320 * This tests the case where the data slice tracks a dynptr (ptr2) 321 * that is at a non-zero offset from the frame pointer (ptr1 is at fp, 322 * ptr2 is at fp - 16). 323 */ 324 SEC("?raw_tp") 325 __failure __msg("invalid mem access 'scalar'") 326 int data_slice_use_after_release2(void *ctx) 327 { 328 struct bpf_dynptr ptr1, ptr2; 329 struct sample *sample; 330 331 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr1); 332 bpf_ringbuf_reserve_dynptr(&ringbuf, sizeof(*sample), 0, &ptr2); 333 334 sample = bpf_dynptr_data(&ptr2, 0, sizeof(*sample)); 335 if (!sample) 336 goto done; 337 338 sample->pid = 23; 339 340 bpf_ringbuf_submit_dynptr(&ptr2, 0); 341 342 /* this should fail */ 343 sample->pid = 23; 344 345 bpf_ringbuf_submit_dynptr(&ptr1, 0); 346 347 return 0; 348 349 done: 350 bpf_ringbuf_discard_dynptr(&ptr2, 0); 351 bpf_ringbuf_discard_dynptr(&ptr1, 0); 352 return 0; 353 } 354 355 /* A data slice must be first checked for NULL */ 356 SEC("?raw_tp") 357 __failure __msg("invalid mem access 'mem_or_null'") 358 int data_slice_missing_null_check1(void *ctx) 359 { 360 struct bpf_dynptr ptr; 361 void *data; 362 363 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr); 364 365 data = bpf_dynptr_data(&ptr, 0, 8); 366 367 /* missing if (!data) check */ 368 369 /* this should fail */ 370 *(__u8 *)data = 3; 371 372 bpf_ringbuf_submit_dynptr(&ptr, 0); 373 return 0; 374 } 375 376 /* A data slice can't be dereferenced if it wasn't checked for null */ 377 SEC("?raw_tp") 378 __failure __msg("invalid mem access 'mem_or_null'") 379 int data_slice_missing_null_check2(void *ctx) 380 { 381 struct bpf_dynptr ptr; 382 __u64 *data1, *data2; 383 384 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr); 385 386 data1 = bpf_dynptr_data(&ptr, 0, 8); 387 data2 = bpf_dynptr_data(&ptr, 0, 8); 388 if (data1) 389 /* this should fail */ 390 *data2 = 3; 391 392 bpf_ringbuf_discard_dynptr(&ptr, 0); 393 return 0; 394 } 395 396 /* Can't pass in a dynptr as an arg to a helper function that doesn't take in a 397 * dynptr argument 398 */ 399 SEC("?raw_tp") 400 __failure __msg("invalid indirect read from stack") 401 int invalid_helper1(void *ctx) 402 { 403 struct bpf_dynptr ptr; 404 405 get_map_val_dynptr(&ptr); 406 407 /* this should fail */ 408 bpf_strncmp((const char *)&ptr, sizeof(ptr), "hello!"); 409 410 return 0; 411 } 412 413 /* A dynptr can't be passed into a helper function at a non-zero offset */ 414 SEC("?raw_tp") 415 __failure __msg("cannot pass in dynptr at an offset=-8") 416 int invalid_helper2(void *ctx) 417 { 418 struct bpf_dynptr ptr; 419 char read_data[64]; 420 421 get_map_val_dynptr(&ptr); 422 423 /* this should fail */ 424 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 8, 0, 0); 425 return 0; 426 } 427 428 /* A bpf_dynptr is invalidated if it's been written into */ 429 SEC("?raw_tp") 430 __failure __msg("Expected an initialized dynptr as arg #1") 431 int invalid_write1(void *ctx) 432 { 433 struct bpf_dynptr ptr; 434 void *data; 435 __u8 x = 0; 436 437 get_map_val_dynptr(&ptr); 438 439 memcpy(&ptr, &x, sizeof(x)); 440 441 /* this should fail */ 442 data = bpf_dynptr_data(&ptr, 0, 1); 443 __sink(data); 444 445 return 0; 446 } 447 448 /* 449 * A bpf_dynptr can't be used as a dynptr if it has been written into at a fixed 450 * offset 451 */ 452 SEC("?raw_tp") 453 __failure __msg("cannot overwrite referenced dynptr") 454 int invalid_write2(void *ctx) 455 { 456 struct bpf_dynptr ptr; 457 char read_data[64]; 458 __u8 x = 0; 459 460 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 461 462 memcpy((void *)&ptr + 8, &x, sizeof(x)); 463 464 /* this should fail */ 465 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 466 467 bpf_ringbuf_submit_dynptr(&ptr, 0); 468 469 return 0; 470 } 471 472 /* 473 * A bpf_dynptr can't be used as a dynptr if it has been written into at a 474 * non-const offset 475 */ 476 SEC("?raw_tp") 477 __failure __msg("cannot overwrite referenced dynptr") 478 int invalid_write3(void *ctx) 479 { 480 struct bpf_dynptr ptr; 481 char stack_buf[16]; 482 unsigned long len; 483 __u8 x = 0; 484 485 bpf_ringbuf_reserve_dynptr(&ringbuf, 8, 0, &ptr); 486 487 memcpy(stack_buf, &val, sizeof(val)); 488 len = stack_buf[0] & 0xf; 489 490 memcpy((void *)&ptr + len, &x, sizeof(x)); 491 492 /* this should fail */ 493 bpf_ringbuf_submit_dynptr(&ptr, 0); 494 495 return 0; 496 } 497 498 static int invalid_write4_callback(__u32 index, void *data) 499 { 500 *(__u32 *)data = 123; 501 502 return 0; 503 } 504 505 /* If the dynptr is written into in a callback function, it should 506 * be invalidated as a dynptr 507 */ 508 SEC("?raw_tp") 509 __failure __msg("cannot overwrite referenced dynptr") 510 int invalid_write4(void *ctx) 511 { 512 struct bpf_dynptr ptr; 513 514 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 515 516 bpf_loop(10, invalid_write4_callback, &ptr, 0); 517 518 /* this should fail */ 519 bpf_ringbuf_submit_dynptr(&ptr, 0); 520 521 return 0; 522 } 523 524 /* A globally-defined bpf_dynptr can't be used (it must reside as a stack frame) */ 525 struct bpf_dynptr global_dynptr; 526 527 SEC("?raw_tp") 528 __failure __msg("type=map_value expected=fp") 529 int global(void *ctx) 530 { 531 /* this should fail */ 532 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &global_dynptr); 533 534 bpf_ringbuf_discard_dynptr(&global_dynptr, 0); 535 536 return 0; 537 } 538 539 /* A direct read should fail */ 540 SEC("?raw_tp") 541 __failure __msg("invalid read from stack") 542 int invalid_read1(void *ctx) 543 { 544 struct bpf_dynptr ptr; 545 546 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 547 548 /* this should fail */ 549 val = *(int *)&ptr; 550 551 bpf_ringbuf_discard_dynptr(&ptr, 0); 552 553 return 0; 554 } 555 556 /* A direct read at an offset should fail */ 557 SEC("?raw_tp") 558 __failure __msg("cannot pass in dynptr at an offset") 559 int invalid_read2(void *ctx) 560 { 561 struct bpf_dynptr ptr; 562 char read_data[64]; 563 564 get_map_val_dynptr(&ptr); 565 566 /* this should fail */ 567 bpf_dynptr_read(read_data, sizeof(read_data), (void *)&ptr + 1, 0, 0); 568 569 return 0; 570 } 571 572 /* A direct read at an offset into the lower stack slot should fail */ 573 SEC("?raw_tp") 574 __failure __msg("invalid read from stack") 575 int invalid_read3(void *ctx) 576 { 577 struct bpf_dynptr ptr1, ptr2; 578 579 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr1); 580 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr2); 581 582 /* this should fail */ 583 memcpy(&val, (void *)&ptr1 + 8, sizeof(val)); 584 585 bpf_ringbuf_discard_dynptr(&ptr1, 0); 586 bpf_ringbuf_discard_dynptr(&ptr2, 0); 587 588 return 0; 589 } 590 591 static int invalid_read4_callback(__u32 index, void *data) 592 { 593 /* this should fail */ 594 val = *(__u32 *)data; 595 596 return 0; 597 } 598 599 /* A direct read within a callback function should fail */ 600 SEC("?raw_tp") 601 __failure __msg("invalid read from stack") 602 int invalid_read4(void *ctx) 603 { 604 struct bpf_dynptr ptr; 605 606 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 607 608 bpf_loop(10, invalid_read4_callback, &ptr, 0); 609 610 bpf_ringbuf_submit_dynptr(&ptr, 0); 611 612 return 0; 613 } 614 615 /* Initializing a dynptr on an offset should fail */ 616 SEC("?raw_tp") 617 __failure __msg("cannot pass in dynptr at an offset=0") 618 int invalid_offset(void *ctx) 619 { 620 struct bpf_dynptr ptr; 621 622 /* this should fail */ 623 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr + 1); 624 625 bpf_ringbuf_discard_dynptr(&ptr, 0); 626 627 return 0; 628 } 629 630 /* Can't release a dynptr twice */ 631 SEC("?raw_tp") 632 __failure __msg("arg 1 is an unacquired reference") 633 int release_twice(void *ctx) 634 { 635 struct bpf_dynptr ptr; 636 637 bpf_ringbuf_reserve_dynptr(&ringbuf, 16, 0, &ptr); 638 639 bpf_ringbuf_discard_dynptr(&ptr, 0); 640 641 /* this second release should fail */ 642 bpf_ringbuf_discard_dynptr(&ptr, 0); 643 644 return 0; 645 } 646 647 static int release_twice_callback_fn(__u32 index, void *data) 648 { 649 /* this should fail */ 650 bpf_ringbuf_discard_dynptr(data, 0); 651 652 return 0; 653 } 654 655 /* Test that releasing a dynptr twice, where one of the releases happens 656 * within a callback function, fails 657 */ 658 SEC("?raw_tp") 659 __failure __msg("arg 1 is an unacquired reference") 660 int release_twice_callback(void *ctx) 661 { 662 struct bpf_dynptr ptr; 663 664 bpf_ringbuf_reserve_dynptr(&ringbuf, 32, 0, &ptr); 665 666 bpf_ringbuf_discard_dynptr(&ptr, 0); 667 668 bpf_loop(10, release_twice_callback_fn, &ptr, 0); 669 670 return 0; 671 } 672 673 /* Reject unsupported local mem types for dynptr_from_mem API */ 674 SEC("?raw_tp") 675 __failure __msg("Unsupported reg type fp for bpf_dynptr_from_mem data") 676 int dynptr_from_mem_invalid_api(void *ctx) 677 { 678 struct bpf_dynptr ptr; 679 int x = 0; 680 681 /* this should fail */ 682 bpf_dynptr_from_mem(&x, sizeof(x), 0, &ptr); 683 684 return 0; 685 } 686 687 SEC("?tc") 688 __failure __msg("cannot overwrite referenced dynptr") __log_level(2) 689 int dynptr_pruning_overwrite(struct __sk_buff *ctx) 690 { 691 asm volatile ( 692 "r9 = 0xeB9F; \ 693 r6 = %[ringbuf] ll; \ 694 r1 = r6; \ 695 r2 = 8; \ 696 r3 = 0; \ 697 r4 = r10; \ 698 r4 += -16; \ 699 call %[bpf_ringbuf_reserve_dynptr]; \ 700 if r0 == 0 goto pjmp1; \ 701 goto pjmp2; \ 702 pjmp1: \ 703 *(u64 *)(r10 - 16) = r9; \ 704 pjmp2: \ 705 r1 = r10; \ 706 r1 += -16; \ 707 r2 = 0; \ 708 call %[bpf_ringbuf_discard_dynptr]; " 709 : 710 : __imm(bpf_ringbuf_reserve_dynptr), 711 __imm(bpf_ringbuf_discard_dynptr), 712 __imm_addr(ringbuf) 713 : __clobber_all 714 ); 715 return 0; 716 } 717 718 SEC("?tc") 719 __success __msg("12: safe") __log_level(2) 720 int dynptr_pruning_stacksafe(struct __sk_buff *ctx) 721 { 722 asm volatile ( 723 "r9 = 0xeB9F; \ 724 r6 = %[ringbuf] ll; \ 725 r1 = r6; \ 726 r2 = 8; \ 727 r3 = 0; \ 728 r4 = r10; \ 729 r4 += -16; \ 730 call %[bpf_ringbuf_reserve_dynptr]; \ 731 if r0 == 0 goto stjmp1; \ 732 goto stjmp2; \ 733 stjmp1: \ 734 r9 = r9; \ 735 stjmp2: \ 736 r1 = r10; \ 737 r1 += -16; \ 738 r2 = 0; \ 739 call %[bpf_ringbuf_discard_dynptr]; " 740 : 741 : __imm(bpf_ringbuf_reserve_dynptr), 742 __imm(bpf_ringbuf_discard_dynptr), 743 __imm_addr(ringbuf) 744 : __clobber_all 745 ); 746 return 0; 747 } 748 749 SEC("?tc") 750 __failure __msg("cannot overwrite referenced dynptr") __log_level(2) 751 int dynptr_pruning_type_confusion(struct __sk_buff *ctx) 752 { 753 asm volatile ( 754 "r6 = %[array_map4] ll; \ 755 r7 = %[ringbuf] ll; \ 756 r1 = r6; \ 757 r2 = r10; \ 758 r2 += -8; \ 759 r9 = 0; \ 760 *(u64 *)(r2 + 0) = r9; \ 761 r3 = r10; \ 762 r3 += -24; \ 763 r9 = 0xeB9FeB9F; \ 764 *(u64 *)(r10 - 16) = r9; \ 765 *(u64 *)(r10 - 24) = r9; \ 766 r9 = 0; \ 767 r4 = 0; \ 768 r8 = r2; \ 769 call %[bpf_map_update_elem]; \ 770 r1 = r6; \ 771 r2 = r8; \ 772 call %[bpf_map_lookup_elem]; \ 773 if r0 != 0 goto tjmp1; \ 774 exit; \ 775 tjmp1: \ 776 r8 = r0; \ 777 r1 = r7; \ 778 r2 = 8; \ 779 r3 = 0; \ 780 r4 = r10; \ 781 r4 += -16; \ 782 r0 = *(u64 *)(r0 + 0); \ 783 call %[bpf_ringbuf_reserve_dynptr]; \ 784 if r0 == 0 goto tjmp2; \ 785 r8 = r8; \ 786 r8 = r8; \ 787 r8 = r8; \ 788 r8 = r8; \ 789 r8 = r8; \ 790 r8 = r8; \ 791 r8 = r8; \ 792 goto tjmp3; \ 793 tjmp2: \ 794 *(u64 *)(r10 - 8) = r9; \ 795 *(u64 *)(r10 - 16) = r9; \ 796 r1 = r8; \ 797 r1 += 8; \ 798 r2 = 0; \ 799 r3 = 0; \ 800 r4 = r10; \ 801 r4 += -16; \ 802 call %[bpf_dynptr_from_mem]; \ 803 tjmp3: \ 804 r1 = r10; \ 805 r1 += -16; \ 806 r2 = 0; \ 807 call %[bpf_ringbuf_discard_dynptr]; " 808 : 809 : __imm(bpf_map_update_elem), 810 __imm(bpf_map_lookup_elem), 811 __imm(bpf_ringbuf_reserve_dynptr), 812 __imm(bpf_dynptr_from_mem), 813 __imm(bpf_ringbuf_discard_dynptr), 814 __imm_addr(array_map4), 815 __imm_addr(ringbuf) 816 : __clobber_all 817 ); 818 return 0; 819 } 820 821 SEC("?tc") 822 __failure __msg("dynptr has to be at a constant offset") __log_level(2) 823 int dynptr_var_off_overwrite(struct __sk_buff *ctx) 824 { 825 asm volatile ( 826 "r9 = 16; \ 827 *(u32 *)(r10 - 4) = r9; \ 828 r8 = *(u32 *)(r10 - 4); \ 829 if r8 >= 0 goto vjmp1; \ 830 r0 = 1; \ 831 exit; \ 832 vjmp1: \ 833 if r8 <= 16 goto vjmp2; \ 834 r0 = 1; \ 835 exit; \ 836 vjmp2: \ 837 r8 &= 16; \ 838 r1 = %[ringbuf] ll; \ 839 r2 = 8; \ 840 r3 = 0; \ 841 r4 = r10; \ 842 r4 += -32; \ 843 r4 += r8; \ 844 call %[bpf_ringbuf_reserve_dynptr]; \ 845 r9 = 0xeB9F; \ 846 *(u64 *)(r10 - 16) = r9; \ 847 r1 = r10; \ 848 r1 += -32; \ 849 r1 += r8; \ 850 r2 = 0; \ 851 call %[bpf_ringbuf_discard_dynptr]; " 852 : 853 : __imm(bpf_ringbuf_reserve_dynptr), 854 __imm(bpf_ringbuf_discard_dynptr), 855 __imm_addr(ringbuf) 856 : __clobber_all 857 ); 858 return 0; 859 } 860 861 SEC("?tc") 862 __failure __msg("cannot overwrite referenced dynptr") __log_level(2) 863 int dynptr_partial_slot_invalidate(struct __sk_buff *ctx) 864 { 865 asm volatile ( 866 "r6 = %[ringbuf] ll; \ 867 r7 = %[array_map4] ll; \ 868 r1 = r7; \ 869 r2 = r10; \ 870 r2 += -8; \ 871 r9 = 0; \ 872 *(u64 *)(r2 + 0) = r9; \ 873 r3 = r2; \ 874 r4 = 0; \ 875 r8 = r2; \ 876 call %[bpf_map_update_elem]; \ 877 r1 = r7; \ 878 r2 = r8; \ 879 call %[bpf_map_lookup_elem]; \ 880 if r0 != 0 goto sjmp1; \ 881 exit; \ 882 sjmp1: \ 883 r7 = r0; \ 884 r1 = r6; \ 885 r2 = 8; \ 886 r3 = 0; \ 887 r4 = r10; \ 888 r4 += -24; \ 889 call %[bpf_ringbuf_reserve_dynptr]; \ 890 *(u64 *)(r10 - 16) = r9; \ 891 r1 = r7; \ 892 r2 = 8; \ 893 r3 = 0; \ 894 r4 = r10; \ 895 r4 += -16; \ 896 call %[bpf_dynptr_from_mem]; \ 897 r1 = r10; \ 898 r1 += -512; \ 899 r2 = 488; \ 900 r3 = r10; \ 901 r3 += -24; \ 902 r4 = 0; \ 903 r5 = 0; \ 904 call %[bpf_dynptr_read]; \ 905 r8 = 1; \ 906 if r0 != 0 goto sjmp2; \ 907 r8 = 0; \ 908 sjmp2: \ 909 r1 = r10; \ 910 r1 += -24; \ 911 r2 = 0; \ 912 call %[bpf_ringbuf_discard_dynptr]; " 913 : 914 : __imm(bpf_map_update_elem), 915 __imm(bpf_map_lookup_elem), 916 __imm(bpf_ringbuf_reserve_dynptr), 917 __imm(bpf_ringbuf_discard_dynptr), 918 __imm(bpf_dynptr_from_mem), 919 __imm(bpf_dynptr_read), 920 __imm_addr(ringbuf), 921 __imm_addr(array_map4) 922 : __clobber_all 923 ); 924 return 0; 925 } 926 927 /* Test that it is allowed to overwrite unreferenced dynptr. */ 928 SEC("?raw_tp") 929 __success 930 int dynptr_overwrite_unref(void *ctx) 931 { 932 struct bpf_dynptr ptr; 933 934 if (get_map_val_dynptr(&ptr)) 935 return 0; 936 if (get_map_val_dynptr(&ptr)) 937 return 0; 938 if (get_map_val_dynptr(&ptr)) 939 return 0; 940 941 return 0; 942 } 943 944 /* Test that slices are invalidated on reinitializing a dynptr. */ 945 SEC("?raw_tp") 946 __failure __msg("invalid mem access 'scalar'") 947 int dynptr_invalidate_slice_reinit(void *ctx) 948 { 949 struct bpf_dynptr ptr; 950 __u8 *p; 951 952 if (get_map_val_dynptr(&ptr)) 953 return 0; 954 p = bpf_dynptr_data(&ptr, 0, 1); 955 if (!p) 956 return 0; 957 if (get_map_val_dynptr(&ptr)) 958 return 0; 959 /* this should fail */ 960 return *p; 961 } 962 963 /* Invalidation of dynptr slices on destruction of dynptr should not miss 964 * mem_or_null pointers. 965 */ 966 SEC("?raw_tp") 967 __failure __msg("R1 type=scalar expected=percpu_ptr_") 968 int dynptr_invalidate_slice_or_null(void *ctx) 969 { 970 struct bpf_dynptr ptr; 971 __u8 *p; 972 973 if (get_map_val_dynptr(&ptr)) 974 return 0; 975 976 p = bpf_dynptr_data(&ptr, 0, 1); 977 *(__u8 *)&ptr = 0; 978 /* this should fail */ 979 bpf_this_cpu_ptr(p); 980 return 0; 981 } 982 983 /* Destruction of dynptr should also any slices obtained from it */ 984 SEC("?raw_tp") 985 __failure __msg("R7 invalid mem access 'scalar'") 986 int dynptr_invalidate_slice_failure(void *ctx) 987 { 988 struct bpf_dynptr ptr1; 989 struct bpf_dynptr ptr2; 990 __u8 *p1, *p2; 991 992 if (get_map_val_dynptr(&ptr1)) 993 return 0; 994 if (get_map_val_dynptr(&ptr2)) 995 return 0; 996 997 p1 = bpf_dynptr_data(&ptr1, 0, 1); 998 if (!p1) 999 return 0; 1000 p2 = bpf_dynptr_data(&ptr2, 0, 1); 1001 if (!p2) 1002 return 0; 1003 1004 *(__u8 *)&ptr1 = 0; 1005 /* this should fail */ 1006 return *p1; 1007 } 1008 1009 /* Invalidation of slices should be scoped and should not prevent dereferencing 1010 * slices of another dynptr after destroying unrelated dynptr 1011 */ 1012 SEC("?raw_tp") 1013 __success 1014 int dynptr_invalidate_slice_success(void *ctx) 1015 { 1016 struct bpf_dynptr ptr1; 1017 struct bpf_dynptr ptr2; 1018 __u8 *p1, *p2; 1019 1020 if (get_map_val_dynptr(&ptr1)) 1021 return 1; 1022 if (get_map_val_dynptr(&ptr2)) 1023 return 1; 1024 1025 p1 = bpf_dynptr_data(&ptr1, 0, 1); 1026 if (!p1) 1027 return 1; 1028 p2 = bpf_dynptr_data(&ptr2, 0, 1); 1029 if (!p2) 1030 return 1; 1031 1032 *(__u8 *)&ptr1 = 0; 1033 return *p2; 1034 } 1035 1036 /* Overwriting referenced dynptr should be rejected */ 1037 SEC("?raw_tp") 1038 __failure __msg("cannot overwrite referenced dynptr") 1039 int dynptr_overwrite_ref(void *ctx) 1040 { 1041 struct bpf_dynptr ptr; 1042 1043 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &ptr); 1044 /* this should fail */ 1045 if (get_map_val_dynptr(&ptr)) 1046 bpf_ringbuf_discard_dynptr(&ptr, 0); 1047 return 0; 1048 } 1049 1050 /* Reject writes to dynptr slot from bpf_dynptr_read */ 1051 SEC("?raw_tp") 1052 __failure __msg("potential write to dynptr at off=-16") 1053 int dynptr_read_into_slot(void *ctx) 1054 { 1055 union { 1056 struct { 1057 char _pad[48]; 1058 struct bpf_dynptr ptr; 1059 }; 1060 char buf[64]; 1061 } data; 1062 1063 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &data.ptr); 1064 /* this should fail */ 1065 bpf_dynptr_read(data.buf, sizeof(data.buf), &data.ptr, 0, 0); 1066 1067 return 0; 1068 } 1069 1070 /* bpf_dynptr_slice()s are read-only and cannot be written to */ 1071 SEC("?tc") 1072 __failure __msg("R0 cannot write into rdonly_mem") 1073 int skb_invalid_slice_write(struct __sk_buff *skb) 1074 { 1075 struct bpf_dynptr ptr; 1076 struct ethhdr *hdr; 1077 char buffer[sizeof(*hdr)] = {}; 1078 1079 bpf_dynptr_from_skb(skb, 0, &ptr); 1080 1081 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1082 if (!hdr) 1083 return SK_DROP; 1084 1085 /* this should fail */ 1086 hdr->h_proto = 1; 1087 1088 return SK_PASS; 1089 } 1090 1091 /* The read-only data slice is invalidated whenever a helper changes packet data */ 1092 SEC("?tc") 1093 __failure __msg("invalid mem access 'scalar'") 1094 int skb_invalid_data_slice1(struct __sk_buff *skb) 1095 { 1096 struct bpf_dynptr ptr; 1097 struct ethhdr *hdr; 1098 char buffer[sizeof(*hdr)] = {}; 1099 1100 bpf_dynptr_from_skb(skb, 0, &ptr); 1101 1102 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1103 if (!hdr) 1104 return SK_DROP; 1105 1106 val = hdr->h_proto; 1107 1108 if (bpf_skb_pull_data(skb, skb->len)) 1109 return SK_DROP; 1110 1111 /* this should fail */ 1112 val = hdr->h_proto; 1113 1114 return SK_PASS; 1115 } 1116 1117 /* The read-write data slice is invalidated whenever a helper changes packet data */ 1118 SEC("?tc") 1119 __failure __msg("invalid mem access 'scalar'") 1120 int skb_invalid_data_slice2(struct __sk_buff *skb) 1121 { 1122 struct bpf_dynptr ptr; 1123 struct ethhdr *hdr; 1124 char buffer[sizeof(*hdr)] = {}; 1125 1126 bpf_dynptr_from_skb(skb, 0, &ptr); 1127 1128 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1129 if (!hdr) 1130 return SK_DROP; 1131 1132 hdr->h_proto = 123; 1133 1134 if (bpf_skb_pull_data(skb, skb->len)) 1135 return SK_DROP; 1136 1137 /* this should fail */ 1138 hdr->h_proto = 1; 1139 1140 return SK_PASS; 1141 } 1142 1143 /* The read-only data slice is invalidated whenever bpf_dynptr_write() is called */ 1144 SEC("?tc") 1145 __failure __msg("invalid mem access 'scalar'") 1146 int skb_invalid_data_slice3(struct __sk_buff *skb) 1147 { 1148 char write_data[64] = "hello there, world!!"; 1149 struct bpf_dynptr ptr; 1150 struct ethhdr *hdr; 1151 char buffer[sizeof(*hdr)] = {}; 1152 1153 bpf_dynptr_from_skb(skb, 0, &ptr); 1154 1155 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1156 if (!hdr) 1157 return SK_DROP; 1158 1159 val = hdr->h_proto; 1160 1161 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0); 1162 1163 /* this should fail */ 1164 val = hdr->h_proto; 1165 1166 return SK_PASS; 1167 } 1168 1169 /* The read-write data slice is invalidated whenever bpf_dynptr_write() is called */ 1170 SEC("?tc") 1171 __failure __msg("invalid mem access 'scalar'") 1172 int skb_invalid_data_slice4(struct __sk_buff *skb) 1173 { 1174 char write_data[64] = "hello there, world!!"; 1175 struct bpf_dynptr ptr; 1176 struct ethhdr *hdr; 1177 char buffer[sizeof(*hdr)] = {}; 1178 1179 bpf_dynptr_from_skb(skb, 0, &ptr); 1180 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1181 if (!hdr) 1182 return SK_DROP; 1183 1184 hdr->h_proto = 123; 1185 1186 bpf_dynptr_write(&ptr, 0, write_data, sizeof(write_data), 0); 1187 1188 /* this should fail */ 1189 hdr->h_proto = 1; 1190 1191 return SK_PASS; 1192 } 1193 1194 /* The read-only data slice is invalidated whenever a helper changes packet data */ 1195 SEC("?xdp") 1196 __failure __msg("invalid mem access 'scalar'") 1197 int xdp_invalid_data_slice1(struct xdp_md *xdp) 1198 { 1199 struct bpf_dynptr ptr; 1200 struct ethhdr *hdr; 1201 char buffer[sizeof(*hdr)] = {}; 1202 1203 bpf_dynptr_from_xdp(xdp, 0, &ptr); 1204 hdr = bpf_dynptr_slice(&ptr, 0, buffer, sizeof(buffer)); 1205 if (!hdr) 1206 return SK_DROP; 1207 1208 val = hdr->h_proto; 1209 1210 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr))) 1211 return XDP_DROP; 1212 1213 /* this should fail */ 1214 val = hdr->h_proto; 1215 1216 return XDP_PASS; 1217 } 1218 1219 /* The read-write data slice is invalidated whenever a helper changes packet data */ 1220 SEC("?xdp") 1221 __failure __msg("invalid mem access 'scalar'") 1222 int xdp_invalid_data_slice2(struct xdp_md *xdp) 1223 { 1224 struct bpf_dynptr ptr; 1225 struct ethhdr *hdr; 1226 char buffer[sizeof(*hdr)] = {}; 1227 1228 bpf_dynptr_from_xdp(xdp, 0, &ptr); 1229 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1230 if (!hdr) 1231 return SK_DROP; 1232 1233 hdr->h_proto = 9; 1234 1235 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr))) 1236 return XDP_DROP; 1237 1238 /* this should fail */ 1239 hdr->h_proto = 1; 1240 1241 return XDP_PASS; 1242 } 1243 1244 /* Only supported prog type can create skb-type dynptrs */ 1245 SEC("?raw_tp") 1246 __failure __msg("calling kernel function bpf_dynptr_from_skb is not allowed") 1247 int skb_invalid_ctx(void *ctx) 1248 { 1249 struct bpf_dynptr ptr; 1250 1251 /* this should fail */ 1252 bpf_dynptr_from_skb(ctx, 0, &ptr); 1253 1254 return 0; 1255 } 1256 1257 /* Reject writes to dynptr slot for uninit arg */ 1258 SEC("?raw_tp") 1259 __failure __msg("potential write to dynptr at off=-16") 1260 int uninit_write_into_slot(void *ctx) 1261 { 1262 struct { 1263 char buf[64]; 1264 struct bpf_dynptr ptr; 1265 } data; 1266 1267 bpf_ringbuf_reserve_dynptr(&ringbuf, 80, 0, &data.ptr); 1268 /* this should fail */ 1269 bpf_get_current_comm(data.buf, 80); 1270 1271 return 0; 1272 } 1273 1274 /* Only supported prog type can create xdp-type dynptrs */ 1275 SEC("?raw_tp") 1276 __failure __msg("calling kernel function bpf_dynptr_from_xdp is not allowed") 1277 int xdp_invalid_ctx(void *ctx) 1278 { 1279 struct bpf_dynptr ptr; 1280 1281 /* this should fail */ 1282 bpf_dynptr_from_xdp(ctx, 0, &ptr); 1283 1284 return 0; 1285 } 1286 1287 __u32 hdr_size = sizeof(struct ethhdr); 1288 /* Can't pass in variable-sized len to bpf_dynptr_slice */ 1289 SEC("?tc") 1290 __failure __msg("unbounded memory access") 1291 int dynptr_slice_var_len1(struct __sk_buff *skb) 1292 { 1293 struct bpf_dynptr ptr; 1294 struct ethhdr *hdr; 1295 char buffer[sizeof(*hdr)] = {}; 1296 1297 bpf_dynptr_from_skb(skb, 0, &ptr); 1298 1299 /* this should fail */ 1300 hdr = bpf_dynptr_slice(&ptr, 0, buffer, hdr_size); 1301 if (!hdr) 1302 return SK_DROP; 1303 1304 return SK_PASS; 1305 } 1306 1307 /* Can't pass in variable-sized len to bpf_dynptr_slice */ 1308 SEC("?tc") 1309 __failure __msg("must be a known constant") 1310 int dynptr_slice_var_len2(struct __sk_buff *skb) 1311 { 1312 char buffer[sizeof(struct ethhdr)] = {}; 1313 struct bpf_dynptr ptr; 1314 struct ethhdr *hdr; 1315 1316 bpf_dynptr_from_skb(skb, 0, &ptr); 1317 1318 if (hdr_size <= sizeof(buffer)) { 1319 /* this should fail */ 1320 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, hdr_size); 1321 if (!hdr) 1322 return SK_DROP; 1323 hdr->h_proto = 12; 1324 } 1325 1326 return SK_PASS; 1327 } 1328 1329 static int callback(__u32 index, void *data) 1330 { 1331 *(__u32 *)data = 123; 1332 1333 return 0; 1334 } 1335 1336 /* If the dynptr is written into in a callback function, its data 1337 * slices should be invalidated as well. 1338 */ 1339 SEC("?raw_tp") 1340 __failure __msg("invalid mem access 'scalar'") 1341 int invalid_data_slices(void *ctx) 1342 { 1343 struct bpf_dynptr ptr; 1344 __u32 *slice; 1345 1346 if (get_map_val_dynptr(&ptr)) 1347 return 0; 1348 1349 slice = bpf_dynptr_data(&ptr, 0, sizeof(__u32)); 1350 if (!slice) 1351 return 0; 1352 1353 bpf_loop(10, callback, &ptr, 0); 1354 1355 /* this should fail */ 1356 *slice = 1; 1357 1358 return 0; 1359 } 1360 1361 /* Program types that don't allow writes to packet data should fail if 1362 * bpf_dynptr_slice_rdwr is called 1363 */ 1364 SEC("cgroup_skb/ingress") 1365 __failure __msg("the prog does not allow writes to packet data") 1366 int invalid_slice_rdwr_rdonly(struct __sk_buff *skb) 1367 { 1368 char buffer[sizeof(struct ethhdr)] = {}; 1369 struct bpf_dynptr ptr; 1370 struct ethhdr *hdr; 1371 1372 bpf_dynptr_from_skb(skb, 0, &ptr); 1373 1374 /* this should fail since cgroup_skb doesn't allow 1375 * changing packet data 1376 */ 1377 hdr = bpf_dynptr_slice_rdwr(&ptr, 0, buffer, sizeof(buffer)); 1378 __sink(hdr); 1379 1380 return 0; 1381 } 1382 1383 /* bpf_dynptr_adjust can only be called on initialized dynptrs */ 1384 SEC("?raw_tp") 1385 __failure __msg("Expected an initialized dynptr as arg #1") 1386 int dynptr_adjust_invalid(void *ctx) 1387 { 1388 struct bpf_dynptr ptr = {}; 1389 1390 /* this should fail */ 1391 bpf_dynptr_adjust(&ptr, 1, 2); 1392 1393 return 0; 1394 } 1395 1396 /* bpf_dynptr_is_null can only be called on initialized dynptrs */ 1397 SEC("?raw_tp") 1398 __failure __msg("Expected an initialized dynptr as arg #1") 1399 int dynptr_is_null_invalid(void *ctx) 1400 { 1401 struct bpf_dynptr ptr = {}; 1402 1403 /* this should fail */ 1404 bpf_dynptr_is_null(&ptr); 1405 1406 return 0; 1407 } 1408 1409 /* bpf_dynptr_is_rdonly can only be called on initialized dynptrs */ 1410 SEC("?raw_tp") 1411 __failure __msg("Expected an initialized dynptr as arg #1") 1412 int dynptr_is_rdonly_invalid(void *ctx) 1413 { 1414 struct bpf_dynptr ptr = {}; 1415 1416 /* this should fail */ 1417 bpf_dynptr_is_rdonly(&ptr); 1418 1419 return 0; 1420 } 1421 1422 /* bpf_dynptr_size can only be called on initialized dynptrs */ 1423 SEC("?raw_tp") 1424 __failure __msg("Expected an initialized dynptr as arg #1") 1425 int dynptr_size_invalid(void *ctx) 1426 { 1427 struct bpf_dynptr ptr = {}; 1428 1429 /* this should fail */ 1430 bpf_dynptr_size(&ptr); 1431 1432 return 0; 1433 } 1434 1435 /* Only initialized dynptrs can be cloned */ 1436 SEC("?raw_tp") 1437 __failure __msg("Expected an initialized dynptr as arg #1") 1438 int clone_invalid1(void *ctx) 1439 { 1440 struct bpf_dynptr ptr1 = {}; 1441 struct bpf_dynptr ptr2; 1442 1443 /* this should fail */ 1444 bpf_dynptr_clone(&ptr1, &ptr2); 1445 1446 return 0; 1447 } 1448 1449 /* Can't overwrite an existing dynptr when cloning */ 1450 SEC("?xdp") 1451 __failure __msg("cannot overwrite referenced dynptr") 1452 int clone_invalid2(struct xdp_md *xdp) 1453 { 1454 struct bpf_dynptr ptr1; 1455 struct bpf_dynptr clone; 1456 1457 bpf_dynptr_from_xdp(xdp, 0, &ptr1); 1458 1459 bpf_ringbuf_reserve_dynptr(&ringbuf, 64, 0, &clone); 1460 1461 /* this should fail */ 1462 bpf_dynptr_clone(&ptr1, &clone); 1463 1464 bpf_ringbuf_submit_dynptr(&clone, 0); 1465 1466 return 0; 1467 } 1468 1469 /* Invalidating a dynptr should invalidate its clones */ 1470 SEC("?raw_tp") 1471 __failure __msg("Expected an initialized dynptr as arg #3") 1472 int clone_invalidate1(void *ctx) 1473 { 1474 struct bpf_dynptr clone; 1475 struct bpf_dynptr ptr; 1476 char read_data[64]; 1477 1478 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1479 1480 bpf_dynptr_clone(&ptr, &clone); 1481 1482 bpf_ringbuf_submit_dynptr(&ptr, 0); 1483 1484 /* this should fail */ 1485 bpf_dynptr_read(read_data, sizeof(read_data), &clone, 0, 0); 1486 1487 return 0; 1488 } 1489 1490 /* Invalidating a dynptr should invalidate its parent */ 1491 SEC("?raw_tp") 1492 __failure __msg("Expected an initialized dynptr as arg #3") 1493 int clone_invalidate2(void *ctx) 1494 { 1495 struct bpf_dynptr ptr; 1496 struct bpf_dynptr clone; 1497 char read_data[64]; 1498 1499 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1500 1501 bpf_dynptr_clone(&ptr, &clone); 1502 1503 bpf_ringbuf_submit_dynptr(&clone, 0); 1504 1505 /* this should fail */ 1506 bpf_dynptr_read(read_data, sizeof(read_data), &ptr, 0, 0); 1507 1508 return 0; 1509 } 1510 1511 /* Invalidating a dynptr should invalidate its siblings */ 1512 SEC("?raw_tp") 1513 __failure __msg("Expected an initialized dynptr as arg #3") 1514 int clone_invalidate3(void *ctx) 1515 { 1516 struct bpf_dynptr ptr; 1517 struct bpf_dynptr clone1; 1518 struct bpf_dynptr clone2; 1519 char read_data[64]; 1520 1521 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1522 1523 bpf_dynptr_clone(&ptr, &clone1); 1524 1525 bpf_dynptr_clone(&ptr, &clone2); 1526 1527 bpf_ringbuf_submit_dynptr(&clone2, 0); 1528 1529 /* this should fail */ 1530 bpf_dynptr_read(read_data, sizeof(read_data), &clone1, 0, 0); 1531 1532 return 0; 1533 } 1534 1535 /* Invalidating a dynptr should invalidate any data slices 1536 * of its clones 1537 */ 1538 SEC("?raw_tp") 1539 __failure __msg("invalid mem access 'scalar'") 1540 int clone_invalidate4(void *ctx) 1541 { 1542 struct bpf_dynptr ptr; 1543 struct bpf_dynptr clone; 1544 int *data; 1545 1546 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1547 1548 bpf_dynptr_clone(&ptr, &clone); 1549 data = bpf_dynptr_data(&clone, 0, sizeof(val)); 1550 if (!data) 1551 return 0; 1552 1553 bpf_ringbuf_submit_dynptr(&ptr, 0); 1554 1555 /* this should fail */ 1556 *data = 123; 1557 1558 return 0; 1559 } 1560 1561 /* Invalidating a dynptr should invalidate any data slices 1562 * of its parent 1563 */ 1564 SEC("?raw_tp") 1565 __failure __msg("invalid mem access 'scalar'") 1566 int clone_invalidate5(void *ctx) 1567 { 1568 struct bpf_dynptr ptr; 1569 struct bpf_dynptr clone; 1570 int *data; 1571 1572 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1573 data = bpf_dynptr_data(&ptr, 0, sizeof(val)); 1574 if (!data) 1575 return 0; 1576 1577 bpf_dynptr_clone(&ptr, &clone); 1578 1579 bpf_ringbuf_submit_dynptr(&clone, 0); 1580 1581 /* this should fail */ 1582 *data = 123; 1583 1584 return 0; 1585 } 1586 1587 /* Invalidating a dynptr should invalidate any data slices 1588 * of its sibling 1589 */ 1590 SEC("?raw_tp") 1591 __failure __msg("invalid mem access 'scalar'") 1592 int clone_invalidate6(void *ctx) 1593 { 1594 struct bpf_dynptr ptr; 1595 struct bpf_dynptr clone1; 1596 struct bpf_dynptr clone2; 1597 int *data; 1598 1599 bpf_ringbuf_reserve_dynptr(&ringbuf, val, 0, &ptr); 1600 1601 bpf_dynptr_clone(&ptr, &clone1); 1602 1603 bpf_dynptr_clone(&ptr, &clone2); 1604 1605 data = bpf_dynptr_data(&clone1, 0, sizeof(val)); 1606 if (!data) 1607 return 0; 1608 1609 bpf_ringbuf_submit_dynptr(&clone2, 0); 1610 1611 /* this should fail */ 1612 *data = 123; 1613 1614 return 0; 1615 } 1616 1617 /* A skb clone's data slices should be invalid anytime packet data changes */ 1618 SEC("?tc") 1619 __failure __msg("invalid mem access 'scalar'") 1620 int clone_skb_packet_data(struct __sk_buff *skb) 1621 { 1622 char buffer[sizeof(__u32)] = {}; 1623 struct bpf_dynptr clone; 1624 struct bpf_dynptr ptr; 1625 __u32 *data; 1626 1627 bpf_dynptr_from_skb(skb, 0, &ptr); 1628 1629 bpf_dynptr_clone(&ptr, &clone); 1630 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer)); 1631 if (!data) 1632 return XDP_DROP; 1633 1634 if (bpf_skb_pull_data(skb, skb->len)) 1635 return SK_DROP; 1636 1637 /* this should fail */ 1638 *data = 123; 1639 1640 return 0; 1641 } 1642 1643 /* A xdp clone's data slices should be invalid anytime packet data changes */ 1644 SEC("?xdp") 1645 __failure __msg("invalid mem access 'scalar'") 1646 int clone_xdp_packet_data(struct xdp_md *xdp) 1647 { 1648 char buffer[sizeof(__u32)] = {}; 1649 struct bpf_dynptr clone; 1650 struct bpf_dynptr ptr; 1651 struct ethhdr *hdr; 1652 __u32 *data; 1653 1654 bpf_dynptr_from_xdp(xdp, 0, &ptr); 1655 1656 bpf_dynptr_clone(&ptr, &clone); 1657 data = bpf_dynptr_slice_rdwr(&clone, 0, buffer, sizeof(buffer)); 1658 if (!data) 1659 return XDP_DROP; 1660 1661 if (bpf_xdp_adjust_head(xdp, 0 - (int)sizeof(*hdr))) 1662 return XDP_DROP; 1663 1664 /* this should fail */ 1665 *data = 123; 1666 1667 return 0; 1668 } 1669 1670 /* Buffers that are provided must be sufficiently long */ 1671 SEC("?cgroup_skb/egress") 1672 __failure __msg("memory, len pair leads to invalid memory access") 1673 int test_dynptr_skb_small_buff(struct __sk_buff *skb) 1674 { 1675 struct bpf_dynptr ptr; 1676 char buffer[8] = {}; 1677 __u64 *data; 1678 1679 if (bpf_dynptr_from_skb(skb, 0, &ptr)) { 1680 err = 1; 1681 return 1; 1682 } 1683 1684 /* This may return NULL. SKB may require a buffer */ 1685 data = bpf_dynptr_slice(&ptr, 0, buffer, 9); 1686 1687 return !!data; 1688 } 1689