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/time.h> 10 #include <sys/uio.h> 11 #include <sys/wait.h> 12 #include <dirent.h> 13 #include <errno.h> 14 #include <fcntl.h> 15 #include <limits.h> 16 #include <poll.h> 17 #include <signal.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <strings.h> 22 #include <sysexits.h> 23 #include <unistd.h> 24 #include <wchar.h> 25 #include <atf-c.h> 26 27 static FILE * __unused 28 new_fp(size_t __len) 29 { 30 static char fpbuf[LINE_MAX]; 31 FILE *fp; 32 33 ATF_REQUIRE(__len <= sizeof(fpbuf)); 34 35 memset(fpbuf, 'A', sizeof(fpbuf) - 1); 36 fpbuf[sizeof(fpbuf) - 1] = '\0'; 37 38 fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); 39 ATF_REQUIRE(fp != NULL); 40 41 return (fp); 42 } 43 44 /* 45 * Create a new symlink to use for readlink(2) style tests, we'll just use a 46 * random target name to have something interesting to look at. 47 */ 48 static const char * __unused 49 new_symlink(size_t __len) 50 { 51 static const char linkname[] = "link"; 52 char target[MAXNAMLEN]; 53 int error; 54 55 ATF_REQUIRE(__len <= sizeof(target)); 56 57 arc4random_buf(target, sizeof(target)); 58 59 error = unlink(linkname); 60 ATF_REQUIRE(error == 0 || errno == ENOENT); 61 62 error = symlink(target, linkname); 63 ATF_REQUIRE(error == 0); 64 65 return (linkname); 66 } 67 68 /* 69 * Constructs a tmpfile that we can use for testing read(2) and friends. 70 */ 71 static int __unused 72 new_tmpfile(void) 73 { 74 char buf[1024]; 75 ssize_t rv; 76 size_t written; 77 int fd; 78 79 fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); 80 ATF_REQUIRE(fd >= 0); 81 82 written = 0; 83 while (written < TMPFILE_SIZE) { 84 rv = write(fd, buf, sizeof(buf)); 85 ATF_REQUIRE(rv > 0); 86 87 written += rv; 88 } 89 90 ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); 91 return (fd); 92 } 93 94 static void 95 disable_coredumps(void) 96 { 97 struct rlimit rl = { 0 }; 98 99 if (setrlimit(RLIMIT_CORE, &rl) == -1) 100 _exit(EX_OSERR); 101 } 102 103 /* 104 * Replaces stdin with a file that we can actually read from, for tests where 105 * we want a FILE * or fd that we can get data from. 106 */ 107 static void __unused 108 replace_stdin(void) 109 { 110 int fd; 111 112 fd = new_tmpfile(); 113 114 (void)dup2(fd, STDIN_FILENO); 115 if (fd != STDIN_FILENO) 116 close(fd); 117 } 118 119 ATF_TC_WITHOUT_HEAD(bcopy_before_end); 120 ATF_TC_BODY(bcopy_before_end, tc) 121 { 122 #define BUF &__stack.__buf 123 struct { 124 uint8_t padding_l; 125 unsigned char __buf[42]; 126 uint8_t padding_r; 127 } __stack; 128 const size_t __bufsz __unused = sizeof(__stack.__buf); 129 const size_t __len = 42 - 1; 130 const size_t __idx __unused = __len - 1; 131 char src[__len + 10]; 132 133 bcopy(src, __stack.__buf, __len); 134 #undef BUF 135 136 } 137 138 ATF_TC_WITHOUT_HEAD(bcopy_end); 139 ATF_TC_BODY(bcopy_end, tc) 140 { 141 #define BUF &__stack.__buf 142 struct { 143 uint8_t padding_l; 144 unsigned char __buf[42]; 145 uint8_t padding_r; 146 } __stack; 147 const size_t __bufsz __unused = sizeof(__stack.__buf); 148 const size_t __len = 42; 149 const size_t __idx __unused = __len - 1; 150 char src[__len + 10]; 151 152 bcopy(src, __stack.__buf, __len); 153 #undef BUF 154 155 } 156 157 ATF_TC_WITHOUT_HEAD(bcopy_heap_before_end); 158 ATF_TC_BODY(bcopy_heap_before_end, tc) 159 { 160 #define BUF __stack.__buf 161 struct { 162 uint8_t padding_l; 163 unsigned char * __buf; 164 uint8_t padding_r; 165 } __stack; 166 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 167 const size_t __len = 42 - 1; 168 const size_t __idx __unused = __len - 1; 169 char src[__len + 10]; 170 171 __stack.__buf = malloc(__bufsz); 172 173 bcopy(src, __stack.__buf, __len); 174 #undef BUF 175 176 } 177 178 ATF_TC_WITHOUT_HEAD(bcopy_heap_end); 179 ATF_TC_BODY(bcopy_heap_end, tc) 180 { 181 #define BUF __stack.__buf 182 struct { 183 uint8_t padding_l; 184 unsigned char * __buf; 185 uint8_t padding_r; 186 } __stack; 187 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 188 const size_t __len = 42; 189 const size_t __idx __unused = __len - 1; 190 char src[__len + 10]; 191 192 __stack.__buf = malloc(__bufsz); 193 194 bcopy(src, __stack.__buf, __len); 195 #undef BUF 196 197 } 198 199 ATF_TC_WITHOUT_HEAD(bcopy_heap_after_end); 200 ATF_TC_BODY(bcopy_heap_after_end, tc) 201 { 202 #define BUF __stack.__buf 203 struct { 204 uint8_t padding_l; 205 unsigned char * __buf; 206 uint8_t padding_r; 207 } __stack; 208 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 209 const size_t __len = 42 + 1; 210 const size_t __idx __unused = __len - 1; 211 pid_t __child; 212 int __status; 213 char src[__len + 10]; 214 215 __child = fork(); 216 ATF_REQUIRE(__child >= 0); 217 if (__child > 0) 218 goto monitor; 219 220 /* Child */ 221 disable_coredumps(); 222 __stack.__buf = malloc(__bufsz); 223 224 bcopy(src, __stack.__buf, __len); 225 _exit(EX_SOFTWARE); /* Should have aborted. */ 226 227 monitor: 228 while (waitpid(__child, &__status, 0) != __child) { 229 ATF_REQUIRE_EQ(EINTR, errno); 230 } 231 232 if (!WIFSIGNALED(__status)) { 233 switch (WEXITSTATUS(__status)) { 234 case EX_SOFTWARE: 235 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 236 break; 237 case EX_OSERR: 238 atf_tc_fail("setrlimit(2) failed"); 239 break; 240 default: 241 atf_tc_fail("child exited with status %d", 242 WEXITSTATUS(__status)); 243 } 244 } else { 245 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 246 } 247 #undef BUF 248 249 } 250 251 ATF_TC_WITHOUT_HEAD(bzero_before_end); 252 ATF_TC_BODY(bzero_before_end, tc) 253 { 254 #define BUF &__stack.__buf 255 struct { 256 uint8_t padding_l; 257 unsigned char __buf[42]; 258 uint8_t padding_r; 259 } __stack; 260 const size_t __bufsz __unused = sizeof(__stack.__buf); 261 const size_t __len = 42 - 1; 262 const size_t __idx __unused = __len - 1; 263 264 bzero(__stack.__buf, __len); 265 #undef BUF 266 267 } 268 269 ATF_TC_WITHOUT_HEAD(bzero_end); 270 ATF_TC_BODY(bzero_end, tc) 271 { 272 #define BUF &__stack.__buf 273 struct { 274 uint8_t padding_l; 275 unsigned char __buf[42]; 276 uint8_t padding_r; 277 } __stack; 278 const size_t __bufsz __unused = sizeof(__stack.__buf); 279 const size_t __len = 42; 280 const size_t __idx __unused = __len - 1; 281 282 bzero(__stack.__buf, __len); 283 #undef BUF 284 285 } 286 287 ATF_TC_WITHOUT_HEAD(bzero_heap_before_end); 288 ATF_TC_BODY(bzero_heap_before_end, tc) 289 { 290 #define BUF __stack.__buf 291 struct { 292 uint8_t padding_l; 293 unsigned char * __buf; 294 uint8_t padding_r; 295 } __stack; 296 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 297 const size_t __len = 42 - 1; 298 const size_t __idx __unused = __len - 1; 299 300 __stack.__buf = malloc(__bufsz); 301 302 bzero(__stack.__buf, __len); 303 #undef BUF 304 305 } 306 307 ATF_TC_WITHOUT_HEAD(bzero_heap_end); 308 ATF_TC_BODY(bzero_heap_end, tc) 309 { 310 #define BUF __stack.__buf 311 struct { 312 uint8_t padding_l; 313 unsigned char * __buf; 314 uint8_t padding_r; 315 } __stack; 316 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 317 const size_t __len = 42; 318 const size_t __idx __unused = __len - 1; 319 320 __stack.__buf = malloc(__bufsz); 321 322 bzero(__stack.__buf, __len); 323 #undef BUF 324 325 } 326 327 ATF_TC_WITHOUT_HEAD(bzero_heap_after_end); 328 ATF_TC_BODY(bzero_heap_after_end, tc) 329 { 330 #define BUF __stack.__buf 331 struct { 332 uint8_t padding_l; 333 unsigned char * __buf; 334 uint8_t padding_r; 335 } __stack; 336 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 337 const size_t __len = 42 + 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 351 bzero(__stack.__buf, __len); 352 _exit(EX_SOFTWARE); /* Should have aborted. */ 353 354 monitor: 355 while (waitpid(__child, &__status, 0) != __child) { 356 ATF_REQUIRE_EQ(EINTR, errno); 357 } 358 359 if (!WIFSIGNALED(__status)) { 360 switch (WEXITSTATUS(__status)) { 361 case EX_SOFTWARE: 362 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 363 break; 364 case EX_OSERR: 365 atf_tc_fail("setrlimit(2) failed"); 366 break; 367 default: 368 atf_tc_fail("child exited with status %d", 369 WEXITSTATUS(__status)); 370 } 371 } else { 372 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 373 } 374 #undef BUF 375 376 } 377 378 ATF_TC_WITHOUT_HEAD(explicit_bzero_before_end); 379 ATF_TC_BODY(explicit_bzero_before_end, tc) 380 { 381 #define BUF &__stack.__buf 382 struct { 383 uint8_t padding_l; 384 unsigned char __buf[42]; 385 uint8_t padding_r; 386 } __stack; 387 const size_t __bufsz __unused = sizeof(__stack.__buf); 388 const size_t __len = 42 - 1; 389 const size_t __idx __unused = __len - 1; 390 391 explicit_bzero(__stack.__buf, __len); 392 #undef BUF 393 394 } 395 396 ATF_TC_WITHOUT_HEAD(explicit_bzero_end); 397 ATF_TC_BODY(explicit_bzero_end, tc) 398 { 399 #define BUF &__stack.__buf 400 struct { 401 uint8_t padding_l; 402 unsigned char __buf[42]; 403 uint8_t padding_r; 404 } __stack; 405 const size_t __bufsz __unused = sizeof(__stack.__buf); 406 const size_t __len = 42; 407 const size_t __idx __unused = __len - 1; 408 409 explicit_bzero(__stack.__buf, __len); 410 #undef BUF 411 412 } 413 414 ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_before_end); 415 ATF_TC_BODY(explicit_bzero_heap_before_end, tc) 416 { 417 #define BUF __stack.__buf 418 struct { 419 uint8_t padding_l; 420 unsigned char * __buf; 421 uint8_t padding_r; 422 } __stack; 423 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 424 const size_t __len = 42 - 1; 425 const size_t __idx __unused = __len - 1; 426 427 __stack.__buf = malloc(__bufsz); 428 429 explicit_bzero(__stack.__buf, __len); 430 #undef BUF 431 432 } 433 434 ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_end); 435 ATF_TC_BODY(explicit_bzero_heap_end, tc) 436 { 437 #define BUF __stack.__buf 438 struct { 439 uint8_t padding_l; 440 unsigned char * __buf; 441 uint8_t padding_r; 442 } __stack; 443 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 444 const size_t __len = 42; 445 const size_t __idx __unused = __len - 1; 446 447 __stack.__buf = malloc(__bufsz); 448 449 explicit_bzero(__stack.__buf, __len); 450 #undef BUF 451 452 } 453 454 ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_after_end); 455 ATF_TC_BODY(explicit_bzero_heap_after_end, tc) 456 { 457 #define BUF __stack.__buf 458 struct { 459 uint8_t padding_l; 460 unsigned char * __buf; 461 uint8_t padding_r; 462 } __stack; 463 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); 464 const size_t __len = 42 + 1; 465 const size_t __idx __unused = __len - 1; 466 pid_t __child; 467 int __status; 468 469 __child = fork(); 470 ATF_REQUIRE(__child >= 0); 471 if (__child > 0) 472 goto monitor; 473 474 /* Child */ 475 disable_coredumps(); 476 __stack.__buf = malloc(__bufsz); 477 478 explicit_bzero(__stack.__buf, __len); 479 _exit(EX_SOFTWARE); /* Should have aborted. */ 480 481 monitor: 482 while (waitpid(__child, &__status, 0) != __child) { 483 ATF_REQUIRE_EQ(EINTR, errno); 484 } 485 486 if (!WIFSIGNALED(__status)) { 487 switch (WEXITSTATUS(__status)) { 488 case EX_SOFTWARE: 489 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 490 break; 491 case EX_OSERR: 492 atf_tc_fail("setrlimit(2) failed"); 493 break; 494 default: 495 atf_tc_fail("child exited with status %d", 496 WEXITSTATUS(__status)); 497 } 498 } else { 499 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 500 } 501 #undef BUF 502 503 } 504 505 ATF_TP_ADD_TCS(tp) 506 { 507 ATF_TP_ADD_TC(tp, bcopy_before_end); 508 ATF_TP_ADD_TC(tp, bcopy_end); 509 ATF_TP_ADD_TC(tp, bcopy_heap_before_end); 510 ATF_TP_ADD_TC(tp, bcopy_heap_end); 511 ATF_TP_ADD_TC(tp, bcopy_heap_after_end); 512 ATF_TP_ADD_TC(tp, bzero_before_end); 513 ATF_TP_ADD_TC(tp, bzero_end); 514 ATF_TP_ADD_TC(tp, bzero_heap_before_end); 515 ATF_TP_ADD_TC(tp, bzero_heap_end); 516 ATF_TP_ADD_TC(tp, bzero_heap_after_end); 517 ATF_TP_ADD_TC(tp, explicit_bzero_before_end); 518 ATF_TP_ADD_TC(tp, explicit_bzero_end); 519 ATF_TP_ADD_TC(tp, explicit_bzero_heap_before_end); 520 ATF_TP_ADD_TC(tp, explicit_bzero_heap_end); 521 ATF_TP_ADD_TC(tp, explicit_bzero_heap_after_end); 522 return (atf_no_error()); 523 } 524