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