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