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