xref: /freebsd/lib/libc/tests/secure/fortify_uio_test.c (revision 1ace24b30cad59c8ae509d0c690aa55b8df73136)
1 /* @generated by `generate-fortify-tests.lua "uio"` */
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/uio.h>
11 #include <sys/wait.h>
12 #include <dirent.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <limits.h>
16 #include <poll.h>
17 #include <signal.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <strings.h>
22 #include <sysexits.h>
23 #include <unistd.h>
24 #include <wchar.h>
25 #include <atf-c.h>
26 
27 static FILE * __unused
28 new_fp(size_t __len)
29 {
30 	static char fpbuf[LINE_MAX];
31 	FILE *fp;
32 
33 	ATF_REQUIRE(__len <= sizeof(fpbuf));
34 
35 	memset(fpbuf, 'A', sizeof(fpbuf) - 1);
36 	fpbuf[sizeof(fpbuf) - 1] = '\0';
37 
38 	fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
39 	ATF_REQUIRE(fp != NULL);
40 
41 	return (fp);
42 }
43 
44 /*
45  * Create a new symlink to use for readlink(2) style tests, we'll just use a
46  * random target name to have something interesting to look at.
47  */
48 static const char * __unused
49 new_symlink(size_t __len)
50 {
51 	static const char linkname[] = "link";
52 	char target[MAXNAMLEN];
53 	int error;
54 
55 	ATF_REQUIRE(__len <= sizeof(target));
56 
57 	arc4random_buf(target, sizeof(target));
58 
59 	error = unlink(linkname);
60 	ATF_REQUIRE(error == 0 || errno == ENOENT);
61 
62 	error = symlink(target, linkname);
63 	ATF_REQUIRE(error == 0);
64 
65 	return (linkname);
66 }
67 
68 /*
69  * Constructs a tmpfile that we can use for testing read(2) and friends.
70  */
71 static int __unused
72 new_tmpfile(void)
73 {
74 	char buf[1024];
75 	ssize_t rv;
76 	size_t written;
77 	int fd;
78 
79 	fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
80 	ATF_REQUIRE(fd >= 0);
81 
82 	written = 0;
83 	while (written < TMPFILE_SIZE) {
84 		rv = write(fd, buf, sizeof(buf));
85 		ATF_REQUIRE(rv > 0);
86 
87 		written += rv;
88 	}
89 
90 	ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
91 	return (fd);
92 }
93 
94 static void
95 disable_coredumps(void)
96 {
97 	struct rlimit rl = { 0 };
98 
99 	if (setrlimit(RLIMIT_CORE, &rl) == -1)
100 		_exit(EX_OSERR);
101 }
102 
103 /*
104  * Replaces stdin with a file that we can actually read from, for tests where
105  * we want a FILE * or fd that we can get data from.
106  */
107 static void __unused
108 replace_stdin(void)
109 {
110 	int fd;
111 
112 	fd = new_tmpfile();
113 
114 	(void)dup2(fd, STDIN_FILENO);
115 	if (fd != STDIN_FILENO)
116 		close(fd);
117 }
118 
119 ATF_TC_WITHOUT_HEAD(readv_before_end);
120 ATF_TC_BODY(readv_before_end, tc)
121 {
122 #define BUF &__stack.__buf
123 	struct {
124 		uint8_t padding_l;
125 		struct iovec __buf[2];
126 		uint8_t padding_r;
127 	} __stack;
128 	const size_t __bufsz __unused = sizeof(__stack.__buf);
129 	const size_t __len = 2 - 1;
130 	const size_t __idx __unused = __len - 1;
131 
132 	readv(STDIN_FILENO, __stack.__buf, __len);
133 #undef BUF
134 
135 }
136 
137 ATF_TC_WITHOUT_HEAD(readv_end);
138 ATF_TC_BODY(readv_end, tc)
139 {
140 #define BUF &__stack.__buf
141 	struct {
142 		uint8_t padding_l;
143 		struct iovec __buf[2];
144 		uint8_t padding_r;
145 	} __stack;
146 	const size_t __bufsz __unused = sizeof(__stack.__buf);
147 	const size_t __len = 2;
148 	const size_t __idx __unused = __len - 1;
149 
150 	readv(STDIN_FILENO, __stack.__buf, __len);
151 #undef BUF
152 
153 }
154 
155 ATF_TC_WITHOUT_HEAD(readv_after_end);
156 ATF_TC_BODY(readv_after_end, tc)
157 {
158 #define BUF &__stack.__buf
159 	struct {
160 		uint8_t padding_l;
161 		struct iovec __buf[2];
162 		uint8_t padding_r;
163 	} __stack;
164 	const size_t __bufsz __unused = sizeof(__stack.__buf);
165 	const size_t __len = 2 + 1;
166 	const size_t __idx __unused = __len - 1;
167 	pid_t __child;
168 	int __status;
169 
170 	__child = fork();
171 	ATF_REQUIRE(__child >= 0);
172 	if (__child > 0)
173 		goto monitor;
174 
175 	/* Child */
176 	disable_coredumps();
177 	readv(STDIN_FILENO, __stack.__buf, __len);
178 	_exit(EX_SOFTWARE);	/* Should have aborted. */
179 
180 monitor:
181 	while (waitpid(__child, &__status, 0) != __child) {
182 		ATF_REQUIRE_EQ(EINTR, errno);
183 	}
184 
185 	if (!WIFSIGNALED(__status)) {
186 		switch (WEXITSTATUS(__status)) {
187 		case EX_SOFTWARE:
188 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
189 			break;
190 		case EX_OSERR:
191 			atf_tc_fail("setrlimit(2) failed");
192 			break;
193 		default:
194 			atf_tc_fail("child exited with status %d",
195 			    WEXITSTATUS(__status));
196 		}
197 	} else {
198 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
199 	}
200 #undef BUF
201 
202 }
203 
204 ATF_TC_WITHOUT_HEAD(readv_heap_before_end);
205 ATF_TC_BODY(readv_heap_before_end, tc)
206 {
207 #define BUF __stack.__buf
208 	struct {
209 		uint8_t padding_l;
210 		struct iovec * __buf;
211 		uint8_t padding_r;
212 	} __stack;
213 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
214 	const size_t __len = 2 - 1;
215 	const size_t __idx __unused = __len - 1;
216 
217 	__stack.__buf = malloc(__bufsz);
218 
219 	readv(STDIN_FILENO, __stack.__buf, __len);
220 #undef BUF
221 
222 }
223 
224 ATF_TC_WITHOUT_HEAD(readv_heap_end);
225 ATF_TC_BODY(readv_heap_end, tc)
226 {
227 #define BUF __stack.__buf
228 	struct {
229 		uint8_t padding_l;
230 		struct iovec * __buf;
231 		uint8_t padding_r;
232 	} __stack;
233 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
234 	const size_t __len = 2;
235 	const size_t __idx __unused = __len - 1;
236 
237 	__stack.__buf = malloc(__bufsz);
238 
239 	readv(STDIN_FILENO, __stack.__buf, __len);
240 #undef BUF
241 
242 }
243 
244 ATF_TC_WITHOUT_HEAD(readv_heap_after_end);
245 ATF_TC_BODY(readv_heap_after_end, tc)
246 {
247 #define BUF __stack.__buf
248 	struct {
249 		uint8_t padding_l;
250 		struct iovec * __buf;
251 		uint8_t padding_r;
252 	} __stack;
253 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
254 	const size_t __len = 2 + 1;
255 	const size_t __idx __unused = __len - 1;
256 	pid_t __child;
257 	int __status;
258 
259 	__child = fork();
260 	ATF_REQUIRE(__child >= 0);
261 	if (__child > 0)
262 		goto monitor;
263 
264 	/* Child */
265 	disable_coredumps();
266 	__stack.__buf = malloc(__bufsz);
267 
268 	readv(STDIN_FILENO, __stack.__buf, __len);
269 	_exit(EX_SOFTWARE);	/* Should have aborted. */
270 
271 monitor:
272 	while (waitpid(__child, &__status, 0) != __child) {
273 		ATF_REQUIRE_EQ(EINTR, errno);
274 	}
275 
276 	if (!WIFSIGNALED(__status)) {
277 		switch (WEXITSTATUS(__status)) {
278 		case EX_SOFTWARE:
279 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
280 			break;
281 		case EX_OSERR:
282 			atf_tc_fail("setrlimit(2) failed");
283 			break;
284 		default:
285 			atf_tc_fail("child exited with status %d",
286 			    WEXITSTATUS(__status));
287 		}
288 	} else {
289 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
290 	}
291 #undef BUF
292 
293 }
294 
295 ATF_TC_WITHOUT_HEAD(readv_iov_before_end);
296 ATF_TC_BODY(readv_iov_before_end, tc)
297 {
298 #define BUF &__stack.__buf
299 	struct {
300 		uint8_t padding_l;
301 		unsigned char __buf[42];
302 		uint8_t padding_r;
303 	} __stack;
304 	const size_t __bufsz __unused = sizeof(__stack.__buf);
305 	const size_t __len = 42 - 1;
306 	const size_t __idx __unused = __len - 1;
307 	struct iovec iov[1];
308 
309 	iov[0].iov_base = __stack.__buf;
310 	iov[0].iov_len = __len;
311 
312 	replace_stdin();
313 
314 	readv(STDIN_FILENO, iov, nitems(iov));
315 #undef BUF
316 
317 }
318 
319 ATF_TC_WITHOUT_HEAD(readv_iov_end);
320 ATF_TC_BODY(readv_iov_end, tc)
321 {
322 #define BUF &__stack.__buf
323 	struct {
324 		uint8_t padding_l;
325 		unsigned char __buf[42];
326 		uint8_t padding_r;
327 	} __stack;
328 	const size_t __bufsz __unused = sizeof(__stack.__buf);
329 	const size_t __len = 42;
330 	const size_t __idx __unused = __len - 1;
331 	struct iovec iov[1];
332 
333 	iov[0].iov_base = __stack.__buf;
334 	iov[0].iov_len = __len;
335 
336 	replace_stdin();
337 
338 	readv(STDIN_FILENO, iov, nitems(iov));
339 #undef BUF
340 
341 }
342 
343 ATF_TC_WITHOUT_HEAD(readv_iov_heap_before_end);
344 ATF_TC_BODY(readv_iov_heap_before_end, tc)
345 {
346 #define BUF __stack.__buf
347 	struct {
348 		uint8_t padding_l;
349 		unsigned char * __buf;
350 		uint8_t padding_r;
351 	} __stack;
352 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
353 	const size_t __len = 42 - 1;
354 	const size_t __idx __unused = __len - 1;
355 	struct iovec iov[1];
356 
357 	__stack.__buf = malloc(__bufsz);
358 	iov[0].iov_base = __stack.__buf;
359 	iov[0].iov_len = __len;
360 
361 	replace_stdin();
362 
363 	readv(STDIN_FILENO, iov, nitems(iov));
364 #undef BUF
365 
366 }
367 
368 ATF_TC_WITHOUT_HEAD(readv_iov_heap_end);
369 ATF_TC_BODY(readv_iov_heap_end, tc)
370 {
371 #define BUF __stack.__buf
372 	struct {
373 		uint8_t padding_l;
374 		unsigned char * __buf;
375 		uint8_t padding_r;
376 	} __stack;
377 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
378 	const size_t __len = 42;
379 	const size_t __idx __unused = __len - 1;
380 	struct iovec iov[1];
381 
382 	__stack.__buf = malloc(__bufsz);
383 	iov[0].iov_base = __stack.__buf;
384 	iov[0].iov_len = __len;
385 
386 	replace_stdin();
387 
388 	readv(STDIN_FILENO, iov, nitems(iov));
389 #undef BUF
390 
391 }
392 
393 ATF_TC_WITHOUT_HEAD(readv_iov_heap_after_end);
394 ATF_TC_BODY(readv_iov_heap_after_end, tc)
395 {
396 #define BUF __stack.__buf
397 	struct {
398 		uint8_t padding_l;
399 		unsigned char * __buf;
400 		uint8_t padding_r;
401 	} __stack;
402 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
403 	const size_t __len = 42 + 1;
404 	const size_t __idx __unused = __len - 1;
405 	pid_t __child;
406 	int __status;
407 	struct iovec iov[1];
408 
409 	__child = fork();
410 	ATF_REQUIRE(__child >= 0);
411 	if (__child > 0)
412 		goto monitor;
413 
414 	/* Child */
415 	disable_coredumps();
416 	__stack.__buf = malloc(__bufsz);
417 	iov[0].iov_base = __stack.__buf;
418 	iov[0].iov_len = __len;
419 
420 	replace_stdin();
421 
422 	readv(STDIN_FILENO, iov, nitems(iov));
423 	_exit(EX_SOFTWARE);	/* Should have aborted. */
424 
425 monitor:
426 	while (waitpid(__child, &__status, 0) != __child) {
427 		ATF_REQUIRE_EQ(EINTR, errno);
428 	}
429 
430 	if (!WIFSIGNALED(__status)) {
431 		switch (WEXITSTATUS(__status)) {
432 		case EX_SOFTWARE:
433 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
434 			break;
435 		case EX_OSERR:
436 			atf_tc_fail("setrlimit(2) failed");
437 			break;
438 		default:
439 			atf_tc_fail("child exited with status %d",
440 			    WEXITSTATUS(__status));
441 		}
442 	} else {
443 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
444 	}
445 #undef BUF
446 
447 }
448 
449 ATF_TC_WITHOUT_HEAD(preadv_before_end);
450 ATF_TC_BODY(preadv_before_end, tc)
451 {
452 #define BUF &__stack.__buf
453 	struct {
454 		uint8_t padding_l;
455 		struct iovec __buf[2];
456 		uint8_t padding_r;
457 	} __stack;
458 	const size_t __bufsz __unused = sizeof(__stack.__buf);
459 	const size_t __len = 2 - 1;
460 	const size_t __idx __unused = __len - 1;
461 
462 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
463 #undef BUF
464 
465 }
466 
467 ATF_TC_WITHOUT_HEAD(preadv_end);
468 ATF_TC_BODY(preadv_end, tc)
469 {
470 #define BUF &__stack.__buf
471 	struct {
472 		uint8_t padding_l;
473 		struct iovec __buf[2];
474 		uint8_t padding_r;
475 	} __stack;
476 	const size_t __bufsz __unused = sizeof(__stack.__buf);
477 	const size_t __len = 2;
478 	const size_t __idx __unused = __len - 1;
479 
480 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
481 #undef BUF
482 
483 }
484 
485 ATF_TC_WITHOUT_HEAD(preadv_after_end);
486 ATF_TC_BODY(preadv_after_end, tc)
487 {
488 #define BUF &__stack.__buf
489 	struct {
490 		uint8_t padding_l;
491 		struct iovec __buf[2];
492 		uint8_t padding_r;
493 	} __stack;
494 	const size_t __bufsz __unused = sizeof(__stack.__buf);
495 	const size_t __len = 2 + 1;
496 	const size_t __idx __unused = __len - 1;
497 	pid_t __child;
498 	int __status;
499 
500 	__child = fork();
501 	ATF_REQUIRE(__child >= 0);
502 	if (__child > 0)
503 		goto monitor;
504 
505 	/* Child */
506 	disable_coredumps();
507 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
508 	_exit(EX_SOFTWARE);	/* Should have aborted. */
509 
510 monitor:
511 	while (waitpid(__child, &__status, 0) != __child) {
512 		ATF_REQUIRE_EQ(EINTR, errno);
513 	}
514 
515 	if (!WIFSIGNALED(__status)) {
516 		switch (WEXITSTATUS(__status)) {
517 		case EX_SOFTWARE:
518 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
519 			break;
520 		case EX_OSERR:
521 			atf_tc_fail("setrlimit(2) failed");
522 			break;
523 		default:
524 			atf_tc_fail("child exited with status %d",
525 			    WEXITSTATUS(__status));
526 		}
527 	} else {
528 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
529 	}
530 #undef BUF
531 
532 }
533 
534 ATF_TC_WITHOUT_HEAD(preadv_heap_before_end);
535 ATF_TC_BODY(preadv_heap_before_end, tc)
536 {
537 #define BUF __stack.__buf
538 	struct {
539 		uint8_t padding_l;
540 		struct iovec * __buf;
541 		uint8_t padding_r;
542 	} __stack;
543 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
544 	const size_t __len = 2 - 1;
545 	const size_t __idx __unused = __len - 1;
546 
547 	__stack.__buf = malloc(__bufsz);
548 
549 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
550 #undef BUF
551 
552 }
553 
554 ATF_TC_WITHOUT_HEAD(preadv_heap_end);
555 ATF_TC_BODY(preadv_heap_end, tc)
556 {
557 #define BUF __stack.__buf
558 	struct {
559 		uint8_t padding_l;
560 		struct iovec * __buf;
561 		uint8_t padding_r;
562 	} __stack;
563 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
564 	const size_t __len = 2;
565 	const size_t __idx __unused = __len - 1;
566 
567 	__stack.__buf = malloc(__bufsz);
568 
569 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
570 #undef BUF
571 
572 }
573 
574 ATF_TC_WITHOUT_HEAD(preadv_heap_after_end);
575 ATF_TC_BODY(preadv_heap_after_end, tc)
576 {
577 #define BUF __stack.__buf
578 	struct {
579 		uint8_t padding_l;
580 		struct iovec * __buf;
581 		uint8_t padding_r;
582 	} __stack;
583 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
584 	const size_t __len = 2 + 1;
585 	const size_t __idx __unused = __len - 1;
586 	pid_t __child;
587 	int __status;
588 
589 	__child = fork();
590 	ATF_REQUIRE(__child >= 0);
591 	if (__child > 0)
592 		goto monitor;
593 
594 	/* Child */
595 	disable_coredumps();
596 	__stack.__buf = malloc(__bufsz);
597 
598 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
599 	_exit(EX_SOFTWARE);	/* Should have aborted. */
600 
601 monitor:
602 	while (waitpid(__child, &__status, 0) != __child) {
603 		ATF_REQUIRE_EQ(EINTR, errno);
604 	}
605 
606 	if (!WIFSIGNALED(__status)) {
607 		switch (WEXITSTATUS(__status)) {
608 		case EX_SOFTWARE:
609 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
610 			break;
611 		case EX_OSERR:
612 			atf_tc_fail("setrlimit(2) failed");
613 			break;
614 		default:
615 			atf_tc_fail("child exited with status %d",
616 			    WEXITSTATUS(__status));
617 		}
618 	} else {
619 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
620 	}
621 #undef BUF
622 
623 }
624 
625 ATF_TC_WITHOUT_HEAD(preadv_iov_before_end);
626 ATF_TC_BODY(preadv_iov_before_end, tc)
627 {
628 #define BUF &__stack.__buf
629 	struct {
630 		uint8_t padding_l;
631 		unsigned char __buf[42];
632 		uint8_t padding_r;
633 	} __stack;
634 	const size_t __bufsz __unused = sizeof(__stack.__buf);
635 	const size_t __len = 42 - 1;
636 	const size_t __idx __unused = __len - 1;
637 	struct iovec iov[1];
638 
639 	iov[0].iov_base = __stack.__buf;
640 	iov[0].iov_len = __len;
641 
642 	replace_stdin();
643 
644 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
645 #undef BUF
646 
647 }
648 
649 ATF_TC_WITHOUT_HEAD(preadv_iov_end);
650 ATF_TC_BODY(preadv_iov_end, tc)
651 {
652 #define BUF &__stack.__buf
653 	struct {
654 		uint8_t padding_l;
655 		unsigned char __buf[42];
656 		uint8_t padding_r;
657 	} __stack;
658 	const size_t __bufsz __unused = sizeof(__stack.__buf);
659 	const size_t __len = 42;
660 	const size_t __idx __unused = __len - 1;
661 	struct iovec iov[1];
662 
663 	iov[0].iov_base = __stack.__buf;
664 	iov[0].iov_len = __len;
665 
666 	replace_stdin();
667 
668 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
669 #undef BUF
670 
671 }
672 
673 ATF_TC_WITHOUT_HEAD(preadv_iov_heap_before_end);
674 ATF_TC_BODY(preadv_iov_heap_before_end, tc)
675 {
676 #define BUF __stack.__buf
677 	struct {
678 		uint8_t padding_l;
679 		unsigned char * __buf;
680 		uint8_t padding_r;
681 	} __stack;
682 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
683 	const size_t __len = 42 - 1;
684 	const size_t __idx __unused = __len - 1;
685 	struct iovec iov[1];
686 
687 	__stack.__buf = malloc(__bufsz);
688 	iov[0].iov_base = __stack.__buf;
689 	iov[0].iov_len = __len;
690 
691 	replace_stdin();
692 
693 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
694 #undef BUF
695 
696 }
697 
698 ATF_TC_WITHOUT_HEAD(preadv_iov_heap_end);
699 ATF_TC_BODY(preadv_iov_heap_end, tc)
700 {
701 #define BUF __stack.__buf
702 	struct {
703 		uint8_t padding_l;
704 		unsigned char * __buf;
705 		uint8_t padding_r;
706 	} __stack;
707 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
708 	const size_t __len = 42;
709 	const size_t __idx __unused = __len - 1;
710 	struct iovec iov[1];
711 
712 	__stack.__buf = malloc(__bufsz);
713 	iov[0].iov_base = __stack.__buf;
714 	iov[0].iov_len = __len;
715 
716 	replace_stdin();
717 
718 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
719 #undef BUF
720 
721 }
722 
723 ATF_TC_WITHOUT_HEAD(preadv_iov_heap_after_end);
724 ATF_TC_BODY(preadv_iov_heap_after_end, tc)
725 {
726 #define BUF __stack.__buf
727 	struct {
728 		uint8_t padding_l;
729 		unsigned char * __buf;
730 		uint8_t padding_r;
731 	} __stack;
732 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
733 	const size_t __len = 42 + 1;
734 	const size_t __idx __unused = __len - 1;
735 	pid_t __child;
736 	int __status;
737 	struct iovec iov[1];
738 
739 	__child = fork();
740 	ATF_REQUIRE(__child >= 0);
741 	if (__child > 0)
742 		goto monitor;
743 
744 	/* Child */
745 	disable_coredumps();
746 	__stack.__buf = malloc(__bufsz);
747 	iov[0].iov_base = __stack.__buf;
748 	iov[0].iov_len = __len;
749 
750 	replace_stdin();
751 
752 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
753 	_exit(EX_SOFTWARE);	/* Should have aborted. */
754 
755 monitor:
756 	while (waitpid(__child, &__status, 0) != __child) {
757 		ATF_REQUIRE_EQ(EINTR, errno);
758 	}
759 
760 	if (!WIFSIGNALED(__status)) {
761 		switch (WEXITSTATUS(__status)) {
762 		case EX_SOFTWARE:
763 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
764 			break;
765 		case EX_OSERR:
766 			atf_tc_fail("setrlimit(2) failed");
767 			break;
768 		default:
769 			atf_tc_fail("child exited with status %d",
770 			    WEXITSTATUS(__status));
771 		}
772 	} else {
773 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
774 	}
775 #undef BUF
776 
777 }
778 
779 ATF_TP_ADD_TCS(tp)
780 {
781 	ATF_TP_ADD_TC(tp, readv_before_end);
782 	ATF_TP_ADD_TC(tp, readv_end);
783 	ATF_TP_ADD_TC(tp, readv_after_end);
784 	ATF_TP_ADD_TC(tp, readv_heap_before_end);
785 	ATF_TP_ADD_TC(tp, readv_heap_end);
786 	ATF_TP_ADD_TC(tp, readv_heap_after_end);
787 	ATF_TP_ADD_TC(tp, readv_iov_before_end);
788 	ATF_TP_ADD_TC(tp, readv_iov_end);
789 	ATF_TP_ADD_TC(tp, readv_iov_heap_before_end);
790 	ATF_TP_ADD_TC(tp, readv_iov_heap_end);
791 	ATF_TP_ADD_TC(tp, readv_iov_heap_after_end);
792 	ATF_TP_ADD_TC(tp, preadv_before_end);
793 	ATF_TP_ADD_TC(tp, preadv_end);
794 	ATF_TP_ADD_TC(tp, preadv_after_end);
795 	ATF_TP_ADD_TC(tp, preadv_heap_before_end);
796 	ATF_TP_ADD_TC(tp, preadv_heap_end);
797 	ATF_TP_ADD_TC(tp, preadv_heap_after_end);
798 	ATF_TP_ADD_TC(tp, preadv_iov_before_end);
799 	ATF_TP_ADD_TC(tp, preadv_iov_end);
800 	ATF_TP_ADD_TC(tp, preadv_iov_heap_before_end);
801 	ATF_TP_ADD_TC(tp, preadv_iov_heap_end);
802 	ATF_TP_ADD_TC(tp, preadv_iov_heap_after_end);
803 	return (atf_no_error());
804 }
805