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