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