1 /* @generated by `generate-fortify-tests.lua "poll"` */ 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(poll_before_end); 117 ATF_TC_BODY(poll_before_end, tc) 118 { 119 #define BUF &__stack.__buf 120 struct { 121 uint8_t padding_l; 122 struct pollfd __buf[4]; 123 uint8_t padding_r; 124 } __stack; 125 const size_t __bufsz __unused = sizeof(__stack.__buf); 126 const size_t __len = 4 - 1; 127 const size_t __idx __unused = __len - 1; 128 129 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 130 __stack.__buf[i].fd = -1; 131 } 132 133 poll(__stack.__buf, __len, 0); 134 #undef BUF 135 136 } 137 138 ATF_TC_WITHOUT_HEAD(poll_end); 139 ATF_TC_BODY(poll_end, tc) 140 { 141 #define BUF &__stack.__buf 142 struct { 143 uint8_t padding_l; 144 struct pollfd __buf[4]; 145 uint8_t padding_r; 146 } __stack; 147 const size_t __bufsz __unused = sizeof(__stack.__buf); 148 const size_t __len = 4; 149 const size_t __idx __unused = __len - 1; 150 151 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 152 __stack.__buf[i].fd = -1; 153 } 154 155 poll(__stack.__buf, __len, 0); 156 #undef BUF 157 158 } 159 160 ATF_TC_WITHOUT_HEAD(poll_after_end); 161 ATF_TC_BODY(poll_after_end, tc) 162 { 163 #define BUF &__stack.__buf 164 struct { 165 uint8_t padding_l; 166 struct pollfd __buf[4]; 167 uint8_t padding_r; 168 } __stack; 169 const size_t __bufsz __unused = sizeof(__stack.__buf); 170 const size_t __len = 4 + 1; 171 const size_t __idx __unused = __len - 1; 172 pid_t __child; 173 int __status; 174 175 __child = fork(); 176 ATF_REQUIRE(__child >= 0); 177 if (__child > 0) 178 goto monitor; 179 180 /* Child */ 181 disable_coredumps(); 182 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 183 __stack.__buf[i].fd = -1; 184 } 185 186 poll(__stack.__buf, __len, 0); 187 _exit(EX_SOFTWARE); /* Should have aborted. */ 188 189 monitor: 190 while (waitpid(__child, &__status, 0) != __child) { 191 ATF_REQUIRE_EQ(EINTR, errno); 192 } 193 194 if (!WIFSIGNALED(__status)) { 195 switch (WEXITSTATUS(__status)) { 196 case EX_SOFTWARE: 197 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 198 break; 199 case EX_OSERR: 200 atf_tc_fail("setrlimit(2) failed"); 201 break; 202 default: 203 atf_tc_fail("child exited with status %d", 204 WEXITSTATUS(__status)); 205 } 206 } else { 207 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 208 } 209 #undef BUF 210 211 } 212 213 ATF_TC_WITHOUT_HEAD(poll_heap_before_end); 214 ATF_TC_BODY(poll_heap_before_end, tc) 215 { 216 #define BUF __stack.__buf 217 struct { 218 uint8_t padding_l; 219 struct pollfd * __buf; 220 uint8_t padding_r; 221 } __stack; 222 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 223 const size_t __len = 4 - 1; 224 const size_t __idx __unused = __len - 1; 225 226 __stack.__buf = malloc(__bufsz); 227 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 228 __stack.__buf[i].fd = -1; 229 } 230 231 poll(__stack.__buf, __len, 0); 232 #undef BUF 233 234 } 235 236 ATF_TC_WITHOUT_HEAD(poll_heap_end); 237 ATF_TC_BODY(poll_heap_end, tc) 238 { 239 #define BUF __stack.__buf 240 struct { 241 uint8_t padding_l; 242 struct pollfd * __buf; 243 uint8_t padding_r; 244 } __stack; 245 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 246 const size_t __len = 4; 247 const size_t __idx __unused = __len - 1; 248 249 __stack.__buf = malloc(__bufsz); 250 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 251 __stack.__buf[i].fd = -1; 252 } 253 254 poll(__stack.__buf, __len, 0); 255 #undef BUF 256 257 } 258 259 ATF_TC_WITHOUT_HEAD(poll_heap_after_end); 260 ATF_TC_BODY(poll_heap_after_end, tc) 261 { 262 #define BUF __stack.__buf 263 struct { 264 uint8_t padding_l; 265 struct pollfd * __buf; 266 uint8_t padding_r; 267 } __stack; 268 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 269 const size_t __len = 4 + 1; 270 const size_t __idx __unused = __len - 1; 271 pid_t __child; 272 int __status; 273 274 __child = fork(); 275 ATF_REQUIRE(__child >= 0); 276 if (__child > 0) 277 goto monitor; 278 279 /* Child */ 280 disable_coredumps(); 281 __stack.__buf = malloc(__bufsz); 282 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 283 __stack.__buf[i].fd = -1; 284 } 285 286 poll(__stack.__buf, __len, 0); 287 _exit(EX_SOFTWARE); /* Should have aborted. */ 288 289 monitor: 290 while (waitpid(__child, &__status, 0) != __child) { 291 ATF_REQUIRE_EQ(EINTR, errno); 292 } 293 294 if (!WIFSIGNALED(__status)) { 295 switch (WEXITSTATUS(__status)) { 296 case EX_SOFTWARE: 297 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 298 break; 299 case EX_OSERR: 300 atf_tc_fail("setrlimit(2) failed"); 301 break; 302 default: 303 atf_tc_fail("child exited with status %d", 304 WEXITSTATUS(__status)); 305 } 306 } else { 307 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 308 } 309 #undef BUF 310 311 } 312 313 ATF_TC_WITHOUT_HEAD(ppoll_before_end); 314 ATF_TC_BODY(ppoll_before_end, tc) 315 { 316 #define BUF &__stack.__buf 317 struct { 318 uint8_t padding_l; 319 struct pollfd __buf[4]; 320 uint8_t padding_r; 321 } __stack; 322 const size_t __bufsz __unused = sizeof(__stack.__buf); 323 const size_t __len = 4 - 1; 324 const size_t __idx __unused = __len - 1; 325 struct timespec tv = { 0 }; 326 327 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 328 __stack.__buf[i].fd = -1; 329 } 330 331 ppoll(__stack.__buf, __len, &tv, NULL); 332 #undef BUF 333 334 } 335 336 ATF_TC_WITHOUT_HEAD(ppoll_end); 337 ATF_TC_BODY(ppoll_end, tc) 338 { 339 #define BUF &__stack.__buf 340 struct { 341 uint8_t padding_l; 342 struct pollfd __buf[4]; 343 uint8_t padding_r; 344 } __stack; 345 const size_t __bufsz __unused = sizeof(__stack.__buf); 346 const size_t __len = 4; 347 const size_t __idx __unused = __len - 1; 348 struct timespec tv = { 0 }; 349 350 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 351 __stack.__buf[i].fd = -1; 352 } 353 354 ppoll(__stack.__buf, __len, &tv, NULL); 355 #undef BUF 356 357 } 358 359 ATF_TC_WITHOUT_HEAD(ppoll_after_end); 360 ATF_TC_BODY(ppoll_after_end, tc) 361 { 362 #define BUF &__stack.__buf 363 struct { 364 uint8_t padding_l; 365 struct pollfd __buf[4]; 366 uint8_t padding_r; 367 } __stack; 368 const size_t __bufsz __unused = sizeof(__stack.__buf); 369 const size_t __len = 4 + 1; 370 const size_t __idx __unused = __len - 1; 371 pid_t __child; 372 int __status; 373 struct timespec tv = { 0 }; 374 375 __child = fork(); 376 ATF_REQUIRE(__child >= 0); 377 if (__child > 0) 378 goto monitor; 379 380 /* Child */ 381 disable_coredumps(); 382 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 383 __stack.__buf[i].fd = -1; 384 } 385 386 ppoll(__stack.__buf, __len, &tv, NULL); 387 _exit(EX_SOFTWARE); /* Should have aborted. */ 388 389 monitor: 390 while (waitpid(__child, &__status, 0) != __child) { 391 ATF_REQUIRE_EQ(EINTR, errno); 392 } 393 394 if (!WIFSIGNALED(__status)) { 395 switch (WEXITSTATUS(__status)) { 396 case EX_SOFTWARE: 397 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 398 break; 399 case EX_OSERR: 400 atf_tc_fail("setrlimit(2) failed"); 401 break; 402 default: 403 atf_tc_fail("child exited with status %d", 404 WEXITSTATUS(__status)); 405 } 406 } else { 407 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 408 } 409 #undef BUF 410 411 } 412 413 ATF_TC_WITHOUT_HEAD(ppoll_heap_before_end); 414 ATF_TC_BODY(ppoll_heap_before_end, tc) 415 { 416 #define BUF __stack.__buf 417 struct { 418 uint8_t padding_l; 419 struct pollfd * __buf; 420 uint8_t padding_r; 421 } __stack; 422 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 423 const size_t __len = 4 - 1; 424 const size_t __idx __unused = __len - 1; 425 struct timespec tv = { 0 }; 426 427 __stack.__buf = malloc(__bufsz); 428 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 429 __stack.__buf[i].fd = -1; 430 } 431 432 ppoll(__stack.__buf, __len, &tv, NULL); 433 #undef BUF 434 435 } 436 437 ATF_TC_WITHOUT_HEAD(ppoll_heap_end); 438 ATF_TC_BODY(ppoll_heap_end, tc) 439 { 440 #define BUF __stack.__buf 441 struct { 442 uint8_t padding_l; 443 struct pollfd * __buf; 444 uint8_t padding_r; 445 } __stack; 446 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 447 const size_t __len = 4; 448 const size_t __idx __unused = __len - 1; 449 struct timespec tv = { 0 }; 450 451 __stack.__buf = malloc(__bufsz); 452 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 453 __stack.__buf[i].fd = -1; 454 } 455 456 ppoll(__stack.__buf, __len, &tv, NULL); 457 #undef BUF 458 459 } 460 461 ATF_TC_WITHOUT_HEAD(ppoll_heap_after_end); 462 ATF_TC_BODY(ppoll_heap_after_end, tc) 463 { 464 #define BUF __stack.__buf 465 struct { 466 uint8_t padding_l; 467 struct pollfd * __buf; 468 uint8_t padding_r; 469 } __stack; 470 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); 471 const size_t __len = 4 + 1; 472 const size_t __idx __unused = __len - 1; 473 pid_t __child; 474 int __status; 475 struct timespec tv = { 0 }; 476 477 __child = fork(); 478 ATF_REQUIRE(__child >= 0); 479 if (__child > 0) 480 goto monitor; 481 482 /* Child */ 483 disable_coredumps(); 484 __stack.__buf = malloc(__bufsz); 485 for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { 486 __stack.__buf[i].fd = -1; 487 } 488 489 ppoll(__stack.__buf, __len, &tv, NULL); 490 _exit(EX_SOFTWARE); /* Should have aborted. */ 491 492 monitor: 493 while (waitpid(__child, &__status, 0) != __child) { 494 ATF_REQUIRE_EQ(EINTR, errno); 495 } 496 497 if (!WIFSIGNALED(__status)) { 498 switch (WEXITSTATUS(__status)) { 499 case EX_SOFTWARE: 500 atf_tc_fail("FORTIFY_SOURCE failed to abort"); 501 break; 502 case EX_OSERR: 503 atf_tc_fail("setrlimit(2) failed"); 504 break; 505 default: 506 atf_tc_fail("child exited with status %d", 507 WEXITSTATUS(__status)); 508 } 509 } else { 510 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); 511 } 512 #undef BUF 513 514 } 515 516 ATF_TP_ADD_TCS(tp) 517 { 518 ATF_TP_ADD_TC(tp, poll_before_end); 519 ATF_TP_ADD_TC(tp, poll_end); 520 ATF_TP_ADD_TC(tp, poll_after_end); 521 ATF_TP_ADD_TC(tp, poll_heap_before_end); 522 ATF_TP_ADD_TC(tp, poll_heap_end); 523 ATF_TP_ADD_TC(tp, poll_heap_after_end); 524 ATF_TP_ADD_TC(tp, ppoll_before_end); 525 ATF_TP_ADD_TC(tp, ppoll_end); 526 ATF_TP_ADD_TC(tp, ppoll_after_end); 527 ATF_TP_ADD_TC(tp, ppoll_heap_before_end); 528 ATF_TP_ADD_TC(tp, ppoll_heap_end); 529 ATF_TP_ADD_TC(tp, ppoll_heap_after_end); 530 return (atf_no_error()); 531 } 532