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