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