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