1 /* @generated by `generate-fortify-tests.lua "uio"` */ 2 3 #define _FORTIFY_SOURCE 2 4 #define TMPFILE_SIZE (1024 * 32) 5 6 #include <sys/param.h> 7 #include <sys/jail.h> 8 #include <sys/random.h> 9 #include <sys/resource.h> 10 #include <sys/select.h> 11 #include <sys/socket.h> 12 #include <sys/time.h> 13 #include <sys/uio.h> 14 #include <sys/wait.h> 15 #include <dirent.h> 16 #include <errno.h> 17 #include <fcntl.h> 18 #include <limits.h> 19 #include <poll.h> 20 #include <signal.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <strings.h> 25 #include <sysexits.h> 26 #include <unistd.h> 27 #include <wchar.h> 28 #include <atf-c.h> 29 30 static FILE * __unused 31 new_fp(size_t __len) 32 { 33 static char fpbuf[LINE_MAX]; 34 FILE *fp; 35 36 ATF_REQUIRE(__len <= sizeof(fpbuf)); 37 38 memset(fpbuf, 'A', sizeof(fpbuf) - 1); 39 fpbuf[sizeof(fpbuf) - 1] = '\0'; 40 41 fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); 42 ATF_REQUIRE(fp != NULL); 43 44 return (fp); 45 } 46 47 /* 48 * Create a new symlink to use for readlink(2) style tests, we'll just use a 49 * random target name to have something interesting to look at. 50 */ 51 static const char * __unused 52 new_symlink(size_t __len) 53 { 54 static const char linkname[] = "link"; 55 char target[MAXNAMLEN]; 56 int error; 57 58 ATF_REQUIRE(__len <= sizeof(target)); 59 60 arc4random_buf(target, sizeof(target)); 61 62 error = unlink(linkname); 63 ATF_REQUIRE(error == 0 || errno == ENOENT); 64 65 error = symlink(target, linkname); 66 ATF_REQUIRE(error == 0); 67 68 return (linkname); 69 } 70 71 /* 72 * For our purposes, first descriptor will be the reader; we'll send both 73 * raw data and a control message over it so that the result can be used for 74 * any of our recv*() tests. 75 */ 76 static void __unused 77 new_socket(int sock[2]) 78 { 79 unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 }; 80 static char sockbuf[256]; 81 ssize_t rv; 82 size_t total = 0; 83 struct msghdr hdr = { 0 }; 84 struct cmsghdr *cmsg; 85 int error, fd; 86 87 error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock); 88 ATF_REQUIRE(error == 0); 89 90 while (total != sizeof(sockbuf)) { 91 rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0); 92 93 ATF_REQUIRE_MSG(rv > 0, 94 "expected bytes sent, got %zd with %zu left (size %zu, total %zu)", 95 rv, sizeof(sockbuf) - total, sizeof(sockbuf), total); 96 ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf), 97 "%zd exceeds total %zu", rv, sizeof(sockbuf)); 98 total += rv; 99 } 100 101 hdr.msg_control = ctrl; 102 hdr.msg_controllen = sizeof(ctrl); 103 104 cmsg = CMSG_FIRSTHDR(&hdr); 105 cmsg->cmsg_level = SOL_SOCKET; 106 cmsg->cmsg_type = SCM_RIGHTS; 107 cmsg->cmsg_len = CMSG_LEN(sizeof(fd)); 108 fd = STDIN_FILENO; 109 memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd)); 110 111 error = sendmsg(sock[1], &hdr, 0); 112 ATF_REQUIRE(error != -1); 113 } 114 115 /* 116 * Constructs a tmpfile that we can use for testing read(2) and friends. 117 */ 118 static int __unused 119 new_tmpfile(void) 120 { 121 char buf[1024]; 122 ssize_t rv; 123 size_t written; 124 int fd; 125 126 fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); 127 ATF_REQUIRE(fd >= 0); 128 129 written = 0; 130 while (written < TMPFILE_SIZE) { 131 rv = write(fd, buf, sizeof(buf)); 132 ATF_REQUIRE(rv > 0); 133 134 written += rv; 135 } 136 137 ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); 138 return (fd); 139 } 140 141 static void 142 disable_coredumps(void) 143 { 144 struct rlimit rl = { 0 }; 145 146 if (setrlimit(RLIMIT_CORE, &rl) == -1) 147 _exit(EX_OSERR); 148 } 149 150 /* 151 * Replaces stdin with a file that we can actually read from, for tests where 152 * we want a FILE * or fd that we can get data from. 153 */ 154 static void __unused 155 replace_stdin(void) 156 { 157 int fd; 158 159 fd = new_tmpfile(); 160 161 (void)dup2(fd, STDIN_FILENO); 162 if (fd != STDIN_FILENO) 163 close(fd); 164 } 165 166 ATF_TC(readv_before_end); 167 ATF_TC_HEAD(readv_before_end, tc) 168 { 169 } 170 ATF_TC_BODY(readv_before_end, tc) 171 { 172 #define BUF &__stack.__buf 173 struct { 174 uint8_t padding_l; 175 struct iovec __buf[2]; 176 uint8_t padding_r; 177 } __stack; 178 const size_t __bufsz __unused = sizeof(__stack.__buf); 179 const size_t __len = 2 - 1; 180 const size_t __idx __unused = __len - 1; 181 182 replace_stdin(); 183 184 for (size_t __i = 0; __i < 2; __i++) { 185 __stack.__buf[__i].iov_base = &__stack.padding_l; 186 __stack.__buf[__i].iov_len = 1; 187 } 188 189 readv(STDIN_FILENO, __stack.__buf, __len); 190 #undef BUF 191 192 } 193 194 ATF_TC(readv_end); 195 ATF_TC_HEAD(readv_end, tc) 196 { 197 } 198 ATF_TC_BODY(readv_end, tc) 199 { 200 #define BUF &__stack.__buf 201 struct { 202 uint8_t padding_l; 203 struct iovec __buf[2]; 204 uint8_t padding_r; 205 } __stack; 206 const size_t __bufsz __unused = sizeof(__stack.__buf); 207 const size_t __len = 2; 208 const size_t __idx __unused = __len - 1; 209 210 replace_stdin(); 211 212 for (size_t __i = 0; __i < 2; __i++) { 213 __stack.__buf[__i].iov_base = &__stack.padding_l; 214 __stack.__buf[__i].iov_len = 1; 215 } 216 217 readv(STDIN_FILENO, __stack.__buf, __len); 218 #undef BUF 219 220 } 221 222 ATF_TC(readv_after_end); 223 ATF_TC_HEAD(readv_after_end, tc) 224 { 225 } 226 ATF_TC_BODY(readv_after_end, tc) 227 { 228 #define BUF &__stack.__buf 229 struct { 230 uint8_t padding_l; 231 struct iovec __buf[2]; 232 uint8_t padding_r; 233 } __stack; 234 const size_t __bufsz __unused = sizeof(__stack.__buf); 235 const size_t __len = 2 + 1; 236 const size_t __idx __unused = __len - 1; 237 pid_t __child; 238 int __status; 239 240 __child = fork(); 241 ATF_REQUIRE(__child >= 0); 242 if (__child > 0) 243 goto monitor; 244 245 /* Child */ 246 disable_coredumps(); 247 replace_stdin(); 248 249 for (size_t __i = 0; __i < 2; __i++) { 250 __stack.__buf[__i].iov_base = &__stack.padding_l; 251 __stack.__buf[__i].iov_len = 1; 252 } 253 254 readv(STDIN_FILENO, __stack.__buf, __len); 255 _exit(EX_SOFTWARE); /* Should have aborted. */ 256 257 monitor: 258 while (waitpid(__child, &__status, 0) != __child) { 259 ATF_REQUIRE_EQ(EINTR, errno); 260 } 261 262 if (!WIFSIGNALED(__status)) { 263 switch (WEXITSTATUS(__status)) { 264 case EX_SOFTWARE: 265 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 266 break; 267 case EX_OSERR: 268 atf_tc_fail("setrlimit(2) failed"); 269 break; 270 default: 271 atf_tc_fail("child exited with status %d", 272 WEXITSTATUS(__status)); 273 } 274 } else { 275 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 276 } 277 #undef BUF 278 279 } 280 281 ATF_TC(readv_heap_before_end); 282 ATF_TC_HEAD(readv_heap_before_end, tc) 283 { 284 } 285 ATF_TC_BODY(readv_heap_before_end, tc) 286 { 287 #define BUF __stack.__buf 288 struct { 289 uint8_t padding_l; 290 struct iovec * __buf; 291 uint8_t padding_r; 292 } __stack; 293 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2); 294 const size_t __len = 2 - 1; 295 const size_t __idx __unused = __len - 1; 296 297 __stack.__buf = malloc(__bufsz); 298 replace_stdin(); 299 300 for (size_t __i = 0; __i < 2; __i++) { 301 __stack.__buf[__i].iov_base = &__stack.padding_l; 302 __stack.__buf[__i].iov_len = 1; 303 } 304 305 readv(STDIN_FILENO, __stack.__buf, __len); 306 #undef BUF 307 308 } 309 310 ATF_TC(readv_heap_end); 311 ATF_TC_HEAD(readv_heap_end, tc) 312 { 313 } 314 ATF_TC_BODY(readv_heap_end, tc) 315 { 316 #define BUF __stack.__buf 317 struct { 318 uint8_t padding_l; 319 struct iovec * __buf; 320 uint8_t padding_r; 321 } __stack; 322 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2); 323 const size_t __len = 2; 324 const size_t __idx __unused = __len - 1; 325 326 __stack.__buf = malloc(__bufsz); 327 replace_stdin(); 328 329 for (size_t __i = 0; __i < 2; __i++) { 330 __stack.__buf[__i].iov_base = &__stack.padding_l; 331 __stack.__buf[__i].iov_len = 1; 332 } 333 334 readv(STDIN_FILENO, __stack.__buf, __len); 335 #undef BUF 336 337 } 338 339 ATF_TC(readv_heap_after_end); 340 ATF_TC_HEAD(readv_heap_after_end, tc) 341 { 342 } 343 ATF_TC_BODY(readv_heap_after_end, tc) 344 { 345 #define BUF __stack.__buf 346 struct { 347 uint8_t padding_l; 348 struct iovec * __buf; 349 uint8_t padding_r; 350 } __stack; 351 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2); 352 const size_t __len = 2 + 1; 353 const size_t __idx __unused = __len - 1; 354 pid_t __child; 355 int __status; 356 357 __child = fork(); 358 ATF_REQUIRE(__child >= 0); 359 if (__child > 0) 360 goto monitor; 361 362 /* Child */ 363 disable_coredumps(); 364 __stack.__buf = malloc(__bufsz); 365 replace_stdin(); 366 367 for (size_t __i = 0; __i < 2; __i++) { 368 __stack.__buf[__i].iov_base = &__stack.padding_l; 369 __stack.__buf[__i].iov_len = 1; 370 } 371 372 readv(STDIN_FILENO, __stack.__buf, __len); 373 _exit(EX_SOFTWARE); /* Should have aborted. */ 374 375 monitor: 376 while (waitpid(__child, &__status, 0) != __child) { 377 ATF_REQUIRE_EQ(EINTR, errno); 378 } 379 380 if (!WIFSIGNALED(__status)) { 381 switch (WEXITSTATUS(__status)) { 382 case EX_SOFTWARE: 383 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 384 break; 385 case EX_OSERR: 386 atf_tc_fail("setrlimit(2) failed"); 387 break; 388 default: 389 atf_tc_fail("child exited with status %d", 390 WEXITSTATUS(__status)); 391 } 392 } else { 393 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 394 } 395 #undef BUF 396 397 } 398 399 ATF_TC(readv_iov_before_end); 400 ATF_TC_HEAD(readv_iov_before_end, tc) 401 { 402 } 403 ATF_TC_BODY(readv_iov_before_end, tc) 404 { 405 #define BUF &__stack.__buf 406 struct { 407 uint8_t padding_l; 408 unsigned char __buf[42]; 409 uint8_t padding_r; 410 } __stack; 411 const size_t __bufsz __unused = sizeof(__stack.__buf); 412 const size_t __len = 42 - 1; 413 const size_t __idx __unused = __len - 1; 414 struct iovec iov[1]; 415 416 replace_stdin(); 417 418 iov[0].iov_base = __stack.__buf; 419 iov[0].iov_len = __len; 420 421 readv(STDIN_FILENO, iov, nitems(iov)); 422 #undef BUF 423 424 } 425 426 ATF_TC(readv_iov_end); 427 ATF_TC_HEAD(readv_iov_end, tc) 428 { 429 } 430 ATF_TC_BODY(readv_iov_end, tc) 431 { 432 #define BUF &__stack.__buf 433 struct { 434 uint8_t padding_l; 435 unsigned char __buf[42]; 436 uint8_t padding_r; 437 } __stack; 438 const size_t __bufsz __unused = sizeof(__stack.__buf); 439 const size_t __len = 42; 440 const size_t __idx __unused = __len - 1; 441 struct iovec iov[1]; 442 443 replace_stdin(); 444 445 iov[0].iov_base = __stack.__buf; 446 iov[0].iov_len = __len; 447 448 readv(STDIN_FILENO, iov, nitems(iov)); 449 #undef BUF 450 451 } 452 453 ATF_TC(readv_iov_heap_before_end); 454 ATF_TC_HEAD(readv_iov_heap_before_end, tc) 455 { 456 } 457 ATF_TC_BODY(readv_iov_heap_before_end, tc) 458 { 459 #define BUF __stack.__buf 460 struct { 461 uint8_t padding_l; 462 unsigned char * __buf; 463 uint8_t padding_r; 464 } __stack; 465 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 466 const size_t __len = 42 - 1; 467 const size_t __idx __unused = __len - 1; 468 struct iovec iov[1]; 469 470 __stack.__buf = malloc(__bufsz); 471 replace_stdin(); 472 473 iov[0].iov_base = __stack.__buf; 474 iov[0].iov_len = __len; 475 476 readv(STDIN_FILENO, iov, nitems(iov)); 477 #undef BUF 478 479 } 480 481 ATF_TC(readv_iov_heap_end); 482 ATF_TC_HEAD(readv_iov_heap_end, tc) 483 { 484 } 485 ATF_TC_BODY(readv_iov_heap_end, tc) 486 { 487 #define BUF __stack.__buf 488 struct { 489 uint8_t padding_l; 490 unsigned char * __buf; 491 uint8_t padding_r; 492 } __stack; 493 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 494 const size_t __len = 42; 495 const size_t __idx __unused = __len - 1; 496 struct iovec iov[1]; 497 498 __stack.__buf = malloc(__bufsz); 499 replace_stdin(); 500 501 iov[0].iov_base = __stack.__buf; 502 iov[0].iov_len = __len; 503 504 readv(STDIN_FILENO, iov, nitems(iov)); 505 #undef BUF 506 507 } 508 509 ATF_TC(readv_iov_heap_after_end); 510 ATF_TC_HEAD(readv_iov_heap_after_end, tc) 511 { 512 } 513 ATF_TC_BODY(readv_iov_heap_after_end, tc) 514 { 515 #define BUF __stack.__buf 516 struct { 517 uint8_t padding_l; 518 unsigned char * __buf; 519 uint8_t padding_r; 520 } __stack; 521 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 522 const size_t __len = 42 + 1; 523 const size_t __idx __unused = __len - 1; 524 pid_t __child; 525 int __status; 526 struct iovec iov[1]; 527 528 __child = fork(); 529 ATF_REQUIRE(__child >= 0); 530 if (__child > 0) 531 goto monitor; 532 533 /* Child */ 534 disable_coredumps(); 535 __stack.__buf = malloc(__bufsz); 536 replace_stdin(); 537 538 iov[0].iov_base = __stack.__buf; 539 iov[0].iov_len = __len; 540 541 readv(STDIN_FILENO, iov, nitems(iov)); 542 _exit(EX_SOFTWARE); /* Should have aborted. */ 543 544 monitor: 545 while (waitpid(__child, &__status, 0) != __child) { 546 ATF_REQUIRE_EQ(EINTR, errno); 547 } 548 549 if (!WIFSIGNALED(__status)) { 550 switch (WEXITSTATUS(__status)) { 551 case EX_SOFTWARE: 552 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 553 break; 554 case EX_OSERR: 555 atf_tc_fail("setrlimit(2) failed"); 556 break; 557 default: 558 atf_tc_fail("child exited with status %d", 559 WEXITSTATUS(__status)); 560 } 561 } else { 562 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 563 } 564 #undef BUF 565 566 } 567 568 ATF_TC(preadv_before_end); 569 ATF_TC_HEAD(preadv_before_end, tc) 570 { 571 } 572 ATF_TC_BODY(preadv_before_end, tc) 573 { 574 #define BUF &__stack.__buf 575 struct { 576 uint8_t padding_l; 577 struct iovec __buf[2]; 578 uint8_t padding_r; 579 } __stack; 580 const size_t __bufsz __unused = sizeof(__stack.__buf); 581 const size_t __len = 2 - 1; 582 const size_t __idx __unused = __len - 1; 583 584 replace_stdin(); 585 586 for (size_t __i = 0; __i < 2; __i++) { 587 __stack.__buf[__i].iov_base = &__stack.padding_l; 588 __stack.__buf[__i].iov_len = 1; 589 } 590 591 preadv(STDIN_FILENO, __stack.__buf, __len, 0); 592 #undef BUF 593 594 } 595 596 ATF_TC(preadv_end); 597 ATF_TC_HEAD(preadv_end, tc) 598 { 599 } 600 ATF_TC_BODY(preadv_end, tc) 601 { 602 #define BUF &__stack.__buf 603 struct { 604 uint8_t padding_l; 605 struct iovec __buf[2]; 606 uint8_t padding_r; 607 } __stack; 608 const size_t __bufsz __unused = sizeof(__stack.__buf); 609 const size_t __len = 2; 610 const size_t __idx __unused = __len - 1; 611 612 replace_stdin(); 613 614 for (size_t __i = 0; __i < 2; __i++) { 615 __stack.__buf[__i].iov_base = &__stack.padding_l; 616 __stack.__buf[__i].iov_len = 1; 617 } 618 619 preadv(STDIN_FILENO, __stack.__buf, __len, 0); 620 #undef BUF 621 622 } 623 624 ATF_TC(preadv_after_end); 625 ATF_TC_HEAD(preadv_after_end, tc) 626 { 627 } 628 ATF_TC_BODY(preadv_after_end, tc) 629 { 630 #define BUF &__stack.__buf 631 struct { 632 uint8_t padding_l; 633 struct iovec __buf[2]; 634 uint8_t padding_r; 635 } __stack; 636 const size_t __bufsz __unused = sizeof(__stack.__buf); 637 const size_t __len = 2 + 1; 638 const size_t __idx __unused = __len - 1; 639 pid_t __child; 640 int __status; 641 642 __child = fork(); 643 ATF_REQUIRE(__child >= 0); 644 if (__child > 0) 645 goto monitor; 646 647 /* Child */ 648 disable_coredumps(); 649 replace_stdin(); 650 651 for (size_t __i = 0; __i < 2; __i++) { 652 __stack.__buf[__i].iov_base = &__stack.padding_l; 653 __stack.__buf[__i].iov_len = 1; 654 } 655 656 preadv(STDIN_FILENO, __stack.__buf, __len, 0); 657 _exit(EX_SOFTWARE); /* Should have aborted. */ 658 659 monitor: 660 while (waitpid(__child, &__status, 0) != __child) { 661 ATF_REQUIRE_EQ(EINTR, errno); 662 } 663 664 if (!WIFSIGNALED(__status)) { 665 switch (WEXITSTATUS(__status)) { 666 case EX_SOFTWARE: 667 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 668 break; 669 case EX_OSERR: 670 atf_tc_fail("setrlimit(2) failed"); 671 break; 672 default: 673 atf_tc_fail("child exited with status %d", 674 WEXITSTATUS(__status)); 675 } 676 } else { 677 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 678 } 679 #undef BUF 680 681 } 682 683 ATF_TC(preadv_heap_before_end); 684 ATF_TC_HEAD(preadv_heap_before_end, tc) 685 { 686 } 687 ATF_TC_BODY(preadv_heap_before_end, tc) 688 { 689 #define BUF __stack.__buf 690 struct { 691 uint8_t padding_l; 692 struct iovec * __buf; 693 uint8_t padding_r; 694 } __stack; 695 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2); 696 const size_t __len = 2 - 1; 697 const size_t __idx __unused = __len - 1; 698 699 __stack.__buf = malloc(__bufsz); 700 replace_stdin(); 701 702 for (size_t __i = 0; __i < 2; __i++) { 703 __stack.__buf[__i].iov_base = &__stack.padding_l; 704 __stack.__buf[__i].iov_len = 1; 705 } 706 707 preadv(STDIN_FILENO, __stack.__buf, __len, 0); 708 #undef BUF 709 710 } 711 712 ATF_TC(preadv_heap_end); 713 ATF_TC_HEAD(preadv_heap_end, tc) 714 { 715 } 716 ATF_TC_BODY(preadv_heap_end, tc) 717 { 718 #define BUF __stack.__buf 719 struct { 720 uint8_t padding_l; 721 struct iovec * __buf; 722 uint8_t padding_r; 723 } __stack; 724 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2); 725 const size_t __len = 2; 726 const size_t __idx __unused = __len - 1; 727 728 __stack.__buf = malloc(__bufsz); 729 replace_stdin(); 730 731 for (size_t __i = 0; __i < 2; __i++) { 732 __stack.__buf[__i].iov_base = &__stack.padding_l; 733 __stack.__buf[__i].iov_len = 1; 734 } 735 736 preadv(STDIN_FILENO, __stack.__buf, __len, 0); 737 #undef BUF 738 739 } 740 741 ATF_TC(preadv_heap_after_end); 742 ATF_TC_HEAD(preadv_heap_after_end, tc) 743 { 744 } 745 ATF_TC_BODY(preadv_heap_after_end, tc) 746 { 747 #define BUF __stack.__buf 748 struct { 749 uint8_t padding_l; 750 struct iovec * __buf; 751 uint8_t padding_r; 752 } __stack; 753 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2); 754 const size_t __len = 2 + 1; 755 const size_t __idx __unused = __len - 1; 756 pid_t __child; 757 int __status; 758 759 __child = fork(); 760 ATF_REQUIRE(__child >= 0); 761 if (__child > 0) 762 goto monitor; 763 764 /* Child */ 765 disable_coredumps(); 766 __stack.__buf = malloc(__bufsz); 767 replace_stdin(); 768 769 for (size_t __i = 0; __i < 2; __i++) { 770 __stack.__buf[__i].iov_base = &__stack.padding_l; 771 __stack.__buf[__i].iov_len = 1; 772 } 773 774 preadv(STDIN_FILENO, __stack.__buf, __len, 0); 775 _exit(EX_SOFTWARE); /* Should have aborted. */ 776 777 monitor: 778 while (waitpid(__child, &__status, 0) != __child) { 779 ATF_REQUIRE_EQ(EINTR, errno); 780 } 781 782 if (!WIFSIGNALED(__status)) { 783 switch (WEXITSTATUS(__status)) { 784 case EX_SOFTWARE: 785 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 786 break; 787 case EX_OSERR: 788 atf_tc_fail("setrlimit(2) failed"); 789 break; 790 default: 791 atf_tc_fail("child exited with status %d", 792 WEXITSTATUS(__status)); 793 } 794 } else { 795 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 796 } 797 #undef BUF 798 799 } 800 801 ATF_TC(preadv_iov_before_end); 802 ATF_TC_HEAD(preadv_iov_before_end, tc) 803 { 804 } 805 ATF_TC_BODY(preadv_iov_before_end, tc) 806 { 807 #define BUF &__stack.__buf 808 struct { 809 uint8_t padding_l; 810 unsigned char __buf[42]; 811 uint8_t padding_r; 812 } __stack; 813 const size_t __bufsz __unused = sizeof(__stack.__buf); 814 const size_t __len = 42 - 1; 815 const size_t __idx __unused = __len - 1; 816 struct iovec iov[1]; 817 818 replace_stdin(); 819 820 iov[0].iov_base = __stack.__buf; 821 iov[0].iov_len = __len; 822 823 preadv(STDIN_FILENO, iov, nitems(iov), 0); 824 #undef BUF 825 826 } 827 828 ATF_TC(preadv_iov_end); 829 ATF_TC_HEAD(preadv_iov_end, tc) 830 { 831 } 832 ATF_TC_BODY(preadv_iov_end, tc) 833 { 834 #define BUF &__stack.__buf 835 struct { 836 uint8_t padding_l; 837 unsigned char __buf[42]; 838 uint8_t padding_r; 839 } __stack; 840 const size_t __bufsz __unused = sizeof(__stack.__buf); 841 const size_t __len = 42; 842 const size_t __idx __unused = __len - 1; 843 struct iovec iov[1]; 844 845 replace_stdin(); 846 847 iov[0].iov_base = __stack.__buf; 848 iov[0].iov_len = __len; 849 850 preadv(STDIN_FILENO, iov, nitems(iov), 0); 851 #undef BUF 852 853 } 854 855 ATF_TC(preadv_iov_heap_before_end); 856 ATF_TC_HEAD(preadv_iov_heap_before_end, tc) 857 { 858 } 859 ATF_TC_BODY(preadv_iov_heap_before_end, tc) 860 { 861 #define BUF __stack.__buf 862 struct { 863 uint8_t padding_l; 864 unsigned char * __buf; 865 uint8_t padding_r; 866 } __stack; 867 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 868 const size_t __len = 42 - 1; 869 const size_t __idx __unused = __len - 1; 870 struct iovec iov[1]; 871 872 __stack.__buf = malloc(__bufsz); 873 replace_stdin(); 874 875 iov[0].iov_base = __stack.__buf; 876 iov[0].iov_len = __len; 877 878 preadv(STDIN_FILENO, iov, nitems(iov), 0); 879 #undef BUF 880 881 } 882 883 ATF_TC(preadv_iov_heap_end); 884 ATF_TC_HEAD(preadv_iov_heap_end, tc) 885 { 886 } 887 ATF_TC_BODY(preadv_iov_heap_end, tc) 888 { 889 #define BUF __stack.__buf 890 struct { 891 uint8_t padding_l; 892 unsigned char * __buf; 893 uint8_t padding_r; 894 } __stack; 895 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 896 const size_t __len = 42; 897 const size_t __idx __unused = __len - 1; 898 struct iovec iov[1]; 899 900 __stack.__buf = malloc(__bufsz); 901 replace_stdin(); 902 903 iov[0].iov_base = __stack.__buf; 904 iov[0].iov_len = __len; 905 906 preadv(STDIN_FILENO, iov, nitems(iov), 0); 907 #undef BUF 908 909 } 910 911 ATF_TC(preadv_iov_heap_after_end); 912 ATF_TC_HEAD(preadv_iov_heap_after_end, tc) 913 { 914 } 915 ATF_TC_BODY(preadv_iov_heap_after_end, tc) 916 { 917 #define BUF __stack.__buf 918 struct { 919 uint8_t padding_l; 920 unsigned char * __buf; 921 uint8_t padding_r; 922 } __stack; 923 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 924 const size_t __len = 42 + 1; 925 const size_t __idx __unused = __len - 1; 926 pid_t __child; 927 int __status; 928 struct iovec iov[1]; 929 930 __child = fork(); 931 ATF_REQUIRE(__child >= 0); 932 if (__child > 0) 933 goto monitor; 934 935 /* Child */ 936 disable_coredumps(); 937 __stack.__buf = malloc(__bufsz); 938 replace_stdin(); 939 940 iov[0].iov_base = __stack.__buf; 941 iov[0].iov_len = __len; 942 943 preadv(STDIN_FILENO, iov, nitems(iov), 0); 944 _exit(EX_SOFTWARE); /* Should have aborted. */ 945 946 monitor: 947 while (waitpid(__child, &__status, 0) != __child) { 948 ATF_REQUIRE_EQ(EINTR, errno); 949 } 950 951 if (!WIFSIGNALED(__status)) { 952 switch (WEXITSTATUS(__status)) { 953 case EX_SOFTWARE: 954 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 955 break; 956 case EX_OSERR: 957 atf_tc_fail("setrlimit(2) failed"); 958 break; 959 default: 960 atf_tc_fail("child exited with status %d", 961 WEXITSTATUS(__status)); 962 } 963 } else { 964 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 965 } 966 #undef BUF 967 968 } 969 970 ATF_TP_ADD_TCS(tp) 971 { 972 ATF_TP_ADD_TC(tp, readv_before_end); 973 ATF_TP_ADD_TC(tp, readv_end); 974 ATF_TP_ADD_TC(tp, readv_after_end); 975 ATF_TP_ADD_TC(tp, readv_heap_before_end); 976 ATF_TP_ADD_TC(tp, readv_heap_end); 977 ATF_TP_ADD_TC(tp, readv_heap_after_end); 978 ATF_TP_ADD_TC(tp, readv_iov_before_end); 979 ATF_TP_ADD_TC(tp, readv_iov_end); 980 ATF_TP_ADD_TC(tp, readv_iov_heap_before_end); 981 ATF_TP_ADD_TC(tp, readv_iov_heap_end); 982 ATF_TP_ADD_TC(tp, readv_iov_heap_after_end); 983 ATF_TP_ADD_TC(tp, preadv_before_end); 984 ATF_TP_ADD_TC(tp, preadv_end); 985 ATF_TP_ADD_TC(tp, preadv_after_end); 986 ATF_TP_ADD_TC(tp, preadv_heap_before_end); 987 ATF_TP_ADD_TC(tp, preadv_heap_end); 988 ATF_TP_ADD_TC(tp, preadv_heap_after_end); 989 ATF_TP_ADD_TC(tp, preadv_iov_before_end); 990 ATF_TP_ADD_TC(tp, preadv_iov_end); 991 ATF_TP_ADD_TC(tp, preadv_iov_heap_before_end); 992 ATF_TP_ADD_TC(tp, preadv_iov_heap_end); 993 ATF_TP_ADD_TC(tp, preadv_iov_heap_after_end); 994 return (atf_no_error()); 995 } 996