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