1 /* @generated by `generate-fortify-tests.lua "poll"` */ 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(poll_before_end); 167 ATF_TC_HEAD(poll_before_end, tc) 168 { 169 } 170 ATF_TC_BODY(poll_before_end, tc) 171 { 172 #define BUF &__stack.__buf 173 struct { 174 uint8_t padding_l; 175 struct pollfd __buf[4]; 176 uint8_t padding_r; 177 } __stack; 178 const size_t __bufsz __unused = sizeof(__stack.__buf); 179 const size_t __len = 4 - 1; 180 const size_t __idx __unused = __len - 1; 181 182 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 183 __stack.__buf[i].fd = -1; 184 } 185 186 poll(__stack.__buf, __len, 0); 187 #undef BUF 188 189 } 190 191 ATF_TC(poll_end); 192 ATF_TC_HEAD(poll_end, tc) 193 { 194 } 195 ATF_TC_BODY(poll_end, tc) 196 { 197 #define BUF &__stack.__buf 198 struct { 199 uint8_t padding_l; 200 struct pollfd __buf[4]; 201 uint8_t padding_r; 202 } __stack; 203 const size_t __bufsz __unused = sizeof(__stack.__buf); 204 const size_t __len = 4; 205 const size_t __idx __unused = __len - 1; 206 207 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 208 __stack.__buf[i].fd = -1; 209 } 210 211 poll(__stack.__buf, __len, 0); 212 #undef BUF 213 214 } 215 216 ATF_TC(poll_after_end); 217 ATF_TC_HEAD(poll_after_end, tc) 218 { 219 } 220 ATF_TC_BODY(poll_after_end, tc) 221 { 222 #define BUF &__stack.__buf 223 struct { 224 uint8_t padding_l; 225 struct pollfd __buf[4]; 226 uint8_t padding_r; 227 } __stack; 228 const size_t __bufsz __unused = sizeof(__stack.__buf); 229 const size_t __len = 4 + 1; 230 const size_t __idx __unused = __len - 1; 231 pid_t __child; 232 int __status; 233 234 __child = fork(); 235 ATF_REQUIRE(__child >= 0); 236 if (__child > 0) 237 goto monitor; 238 239 /* Child */ 240 disable_coredumps(); 241 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 242 __stack.__buf[i].fd = -1; 243 } 244 245 poll(__stack.__buf, __len, 0); 246 _exit(EX_SOFTWARE); /* Should have aborted. */ 247 248 monitor: 249 while (waitpid(__child, &__status, 0) != __child) { 250 ATF_REQUIRE_EQ(EINTR, errno); 251 } 252 253 if (!WIFSIGNALED(__status)) { 254 switch (WEXITSTATUS(__status)) { 255 case EX_SOFTWARE: 256 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 257 break; 258 case EX_OSERR: 259 atf_tc_fail("setrlimit(2) failed"); 260 break; 261 default: 262 atf_tc_fail("child exited with status %d", 263 WEXITSTATUS(__status)); 264 } 265 } else { 266 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 267 } 268 #undef BUF 269 270 } 271 272 ATF_TC(poll_heap_before_end); 273 ATF_TC_HEAD(poll_heap_before_end, tc) 274 { 275 } 276 ATF_TC_BODY(poll_heap_before_end, tc) 277 { 278 #define BUF __stack.__buf 279 struct { 280 uint8_t padding_l; 281 struct pollfd * __buf; 282 uint8_t padding_r; 283 } __stack; 284 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 285 const size_t __len = 4 - 1; 286 const size_t __idx __unused = __len - 1; 287 288 __stack.__buf = malloc(__bufsz); 289 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 290 __stack.__buf[i].fd = -1; 291 } 292 293 poll(__stack.__buf, __len, 0); 294 #undef BUF 295 296 } 297 298 ATF_TC(poll_heap_end); 299 ATF_TC_HEAD(poll_heap_end, tc) 300 { 301 } 302 ATF_TC_BODY(poll_heap_end, tc) 303 { 304 #define BUF __stack.__buf 305 struct { 306 uint8_t padding_l; 307 struct pollfd * __buf; 308 uint8_t padding_r; 309 } __stack; 310 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 311 const size_t __len = 4; 312 const size_t __idx __unused = __len - 1; 313 314 __stack.__buf = malloc(__bufsz); 315 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 316 __stack.__buf[i].fd = -1; 317 } 318 319 poll(__stack.__buf, __len, 0); 320 #undef BUF 321 322 } 323 324 ATF_TC(poll_heap_after_end); 325 ATF_TC_HEAD(poll_heap_after_end, tc) 326 { 327 } 328 ATF_TC_BODY(poll_heap_after_end, tc) 329 { 330 #define BUF __stack.__buf 331 struct { 332 uint8_t padding_l; 333 struct pollfd * __buf; 334 uint8_t padding_r; 335 } __stack; 336 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 337 const size_t __len = 4 + 1; 338 const size_t __idx __unused = __len - 1; 339 pid_t __child; 340 int __status; 341 342 __child = fork(); 343 ATF_REQUIRE(__child >= 0); 344 if (__child > 0) 345 goto monitor; 346 347 /* Child */ 348 disable_coredumps(); 349 __stack.__buf = malloc(__bufsz); 350 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 351 __stack.__buf[i].fd = -1; 352 } 353 354 poll(__stack.__buf, __len, 0); 355 _exit(EX_SOFTWARE); /* Should have aborted. */ 356 357 monitor: 358 while (waitpid(__child, &__status, 0) != __child) { 359 ATF_REQUIRE_EQ(EINTR, errno); 360 } 361 362 if (!WIFSIGNALED(__status)) { 363 switch (WEXITSTATUS(__status)) { 364 case EX_SOFTWARE: 365 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 366 break; 367 case EX_OSERR: 368 atf_tc_fail("setrlimit(2) failed"); 369 break; 370 default: 371 atf_tc_fail("child exited with status %d", 372 WEXITSTATUS(__status)); 373 } 374 } else { 375 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 376 } 377 #undef BUF 378 379 } 380 381 ATF_TC(ppoll_before_end); 382 ATF_TC_HEAD(ppoll_before_end, tc) 383 { 384 } 385 ATF_TC_BODY(ppoll_before_end, tc) 386 { 387 #define BUF &__stack.__buf 388 struct { 389 uint8_t padding_l; 390 struct pollfd __buf[4]; 391 uint8_t padding_r; 392 } __stack; 393 const size_t __bufsz __unused = sizeof(__stack.__buf); 394 const size_t __len = 4 - 1; 395 const size_t __idx __unused = __len - 1; 396 struct timespec tv = { 0 }; 397 398 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 399 __stack.__buf[i].fd = -1; 400 } 401 402 ppoll(__stack.__buf, __len, &tv, NULL); 403 #undef BUF 404 405 } 406 407 ATF_TC(ppoll_end); 408 ATF_TC_HEAD(ppoll_end, tc) 409 { 410 } 411 ATF_TC_BODY(ppoll_end, tc) 412 { 413 #define BUF &__stack.__buf 414 struct { 415 uint8_t padding_l; 416 struct pollfd __buf[4]; 417 uint8_t padding_r; 418 } __stack; 419 const size_t __bufsz __unused = sizeof(__stack.__buf); 420 const size_t __len = 4; 421 const size_t __idx __unused = __len - 1; 422 struct timespec tv = { 0 }; 423 424 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 425 __stack.__buf[i].fd = -1; 426 } 427 428 ppoll(__stack.__buf, __len, &tv, NULL); 429 #undef BUF 430 431 } 432 433 ATF_TC(ppoll_after_end); 434 ATF_TC_HEAD(ppoll_after_end, tc) 435 { 436 } 437 ATF_TC_BODY(ppoll_after_end, tc) 438 { 439 #define BUF &__stack.__buf 440 struct { 441 uint8_t padding_l; 442 struct pollfd __buf[4]; 443 uint8_t padding_r; 444 } __stack; 445 const size_t __bufsz __unused = sizeof(__stack.__buf); 446 const size_t __len = 4 + 1; 447 const size_t __idx __unused = __len - 1; 448 pid_t __child; 449 int __status; 450 struct timespec tv = { 0 }; 451 452 __child = fork(); 453 ATF_REQUIRE(__child >= 0); 454 if (__child > 0) 455 goto monitor; 456 457 /* Child */ 458 disable_coredumps(); 459 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 460 __stack.__buf[i].fd = -1; 461 } 462 463 ppoll(__stack.__buf, __len, &tv, NULL); 464 _exit(EX_SOFTWARE); /* Should have aborted. */ 465 466 monitor: 467 while (waitpid(__child, &__status, 0) != __child) { 468 ATF_REQUIRE_EQ(EINTR, errno); 469 } 470 471 if (!WIFSIGNALED(__status)) { 472 switch (WEXITSTATUS(__status)) { 473 case EX_SOFTWARE: 474 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 475 break; 476 case EX_OSERR: 477 atf_tc_fail("setrlimit(2) failed"); 478 break; 479 default: 480 atf_tc_fail("child exited with status %d", 481 WEXITSTATUS(__status)); 482 } 483 } else { 484 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 485 } 486 #undef BUF 487 488 } 489 490 ATF_TC(ppoll_heap_before_end); 491 ATF_TC_HEAD(ppoll_heap_before_end, tc) 492 { 493 } 494 ATF_TC_BODY(ppoll_heap_before_end, tc) 495 { 496 #define BUF __stack.__buf 497 struct { 498 uint8_t padding_l; 499 struct pollfd * __buf; 500 uint8_t padding_r; 501 } __stack; 502 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 503 const size_t __len = 4 - 1; 504 const size_t __idx __unused = __len - 1; 505 struct timespec tv = { 0 }; 506 507 __stack.__buf = malloc(__bufsz); 508 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 509 __stack.__buf[i].fd = -1; 510 } 511 512 ppoll(__stack.__buf, __len, &tv, NULL); 513 #undef BUF 514 515 } 516 517 ATF_TC(ppoll_heap_end); 518 ATF_TC_HEAD(ppoll_heap_end, tc) 519 { 520 } 521 ATF_TC_BODY(ppoll_heap_end, tc) 522 { 523 #define BUF __stack.__buf 524 struct { 525 uint8_t padding_l; 526 struct pollfd * __buf; 527 uint8_t padding_r; 528 } __stack; 529 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 530 const size_t __len = 4; 531 const size_t __idx __unused = __len - 1; 532 struct timespec tv = { 0 }; 533 534 __stack.__buf = malloc(__bufsz); 535 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 536 __stack.__buf[i].fd = -1; 537 } 538 539 ppoll(__stack.__buf, __len, &tv, NULL); 540 #undef BUF 541 542 } 543 544 ATF_TC(ppoll_heap_after_end); 545 ATF_TC_HEAD(ppoll_heap_after_end, tc) 546 { 547 } 548 ATF_TC_BODY(ppoll_heap_after_end, tc) 549 { 550 #define BUF __stack.__buf 551 struct { 552 uint8_t padding_l; 553 struct pollfd * __buf; 554 uint8_t padding_r; 555 } __stack; 556 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 557 const size_t __len = 4 + 1; 558 const size_t __idx __unused = __len - 1; 559 pid_t __child; 560 int __status; 561 struct timespec tv = { 0 }; 562 563 __child = fork(); 564 ATF_REQUIRE(__child >= 0); 565 if (__child > 0) 566 goto monitor; 567 568 /* Child */ 569 disable_coredumps(); 570 __stack.__buf = malloc(__bufsz); 571 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 572 __stack.__buf[i].fd = -1; 573 } 574 575 ppoll(__stack.__buf, __len, &tv, NULL); 576 _exit(EX_SOFTWARE); /* Should have aborted. */ 577 578 monitor: 579 while (waitpid(__child, &__status, 0) != __child) { 580 ATF_REQUIRE_EQ(EINTR, errno); 581 } 582 583 if (!WIFSIGNALED(__status)) { 584 switch (WEXITSTATUS(__status)) { 585 case EX_SOFTWARE: 586 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 587 break; 588 case EX_OSERR: 589 atf_tc_fail("setrlimit(2) failed"); 590 break; 591 default: 592 atf_tc_fail("child exited with status %d", 593 WEXITSTATUS(__status)); 594 } 595 } else { 596 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 597 } 598 #undef BUF 599 600 } 601 602 ATF_TP_ADD_TCS(tp) 603 { 604 ATF_TP_ADD_TC(tp, poll_before_end); 605 ATF_TP_ADD_TC(tp, poll_end); 606 ATF_TP_ADD_TC(tp, poll_after_end); 607 ATF_TP_ADD_TC(tp, poll_heap_before_end); 608 ATF_TP_ADD_TC(tp, poll_heap_end); 609 ATF_TP_ADD_TC(tp, poll_heap_after_end); 610 ATF_TP_ADD_TC(tp, ppoll_before_end); 611 ATF_TP_ADD_TC(tp, ppoll_end); 612 ATF_TP_ADD_TC(tp, ppoll_after_end); 613 ATF_TP_ADD_TC(tp, ppoll_heap_before_end); 614 ATF_TP_ADD_TC(tp, ppoll_heap_end); 615 ATF_TP_ADD_TC(tp, ppoll_heap_after_end); 616 return (atf_no_error()); 617 } 618