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