xref: /freebsd/lib/libc/tests/secure/fortify_uio_test.c (revision f9bc005b8ef3b507a5ecbc2d7fe4411ef70eff38)
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
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
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
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
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
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
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);
167 ATF_TC_HEAD(readv_before_end, tc)
168 {
169 }
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 	replace_stdin();
183 
184 	for (size_t __i = 0; __i < 2; __i++) {
185 		__stack.__buf[__i].iov_base = &__stack.padding_l;
186 		__stack.__buf[__i].iov_len = 1;
187 	}
188 
189 	readv(STDIN_FILENO, __stack.__buf, __len);
190 #undef BUF
191 
192 }
193 
194 ATF_TC(readv_end);
195 ATF_TC_HEAD(readv_end, tc)
196 {
197 }
198 ATF_TC_BODY(readv_end, tc)
199 {
200 #define BUF &__stack.__buf
201 	struct {
202 		uint8_t padding_l;
203 		struct iovec __buf[2];
204 		uint8_t padding_r;
205 	} __stack;
206 	const size_t __bufsz __unused = sizeof(__stack.__buf);
207 	const size_t __len = 2;
208 	const size_t __idx __unused = __len - 1;
209 
210 	replace_stdin();
211 
212 	for (size_t __i = 0; __i < 2; __i++) {
213 		__stack.__buf[__i].iov_base = &__stack.padding_l;
214 		__stack.__buf[__i].iov_len = 1;
215 	}
216 
217 	readv(STDIN_FILENO, __stack.__buf, __len);
218 #undef BUF
219 
220 }
221 
222 ATF_TC(readv_after_end);
223 ATF_TC_HEAD(readv_after_end, tc)
224 {
225 }
226 ATF_TC_BODY(readv_after_end, tc)
227 {
228 #define BUF &__stack.__buf
229 	struct {
230 		uint8_t padding_l;
231 		struct iovec __buf[2];
232 		uint8_t padding_r;
233 	} __stack;
234 	const size_t __bufsz __unused = sizeof(__stack.__buf);
235 	const size_t __len = 2 + 1;
236 	const size_t __idx __unused = __len - 1;
237 	pid_t __child;
238 	int __status;
239 
240 	__child = fork();
241 	ATF_REQUIRE(__child >= 0);
242 	if (__child > 0)
243 		goto monitor;
244 
245 	/* Child */
246 	disable_coredumps();
247 	replace_stdin();
248 
249 	for (size_t __i = 0; __i < 2; __i++) {
250 		__stack.__buf[__i].iov_base = &__stack.padding_l;
251 		__stack.__buf[__i].iov_len = 1;
252 	}
253 
254 	readv(STDIN_FILENO, __stack.__buf, __len);
255 	_exit(EX_SOFTWARE);	/* Should have aborted. */
256 
257 monitor:
258 	while (waitpid(__child, &__status, 0) != __child) {
259 		ATF_REQUIRE_EQ(EINTR, errno);
260 	}
261 
262 	if (!WIFSIGNALED(__status)) {
263 		switch (WEXITSTATUS(__status)) {
264 		case EX_SOFTWARE:
265 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
266 			break;
267 		case EX_OSERR:
268 			atf_tc_fail("setrlimit(2) failed");
269 			break;
270 		default:
271 			atf_tc_fail("child exited with status %d",
272 			    WEXITSTATUS(__status));
273 		}
274 	} else {
275 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
276 	}
277 #undef BUF
278 
279 }
280 
281 ATF_TC(readv_heap_before_end);
282 ATF_TC_HEAD(readv_heap_before_end, tc)
283 {
284 }
285 ATF_TC_BODY(readv_heap_before_end, tc)
286 {
287 #define BUF __stack.__buf
288 	struct {
289 		uint8_t padding_l;
290 		struct iovec * __buf;
291 		uint8_t padding_r;
292 	} __stack;
293 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
294 	const size_t __len = 2 - 1;
295 	const size_t __idx __unused = __len - 1;
296 
297 	__stack.__buf = malloc(__bufsz);
298 	replace_stdin();
299 
300 	for (size_t __i = 0; __i < 2; __i++) {
301 		__stack.__buf[__i].iov_base = &__stack.padding_l;
302 		__stack.__buf[__i].iov_len = 1;
303 	}
304 
305 	readv(STDIN_FILENO, __stack.__buf, __len);
306 #undef BUF
307 
308 }
309 
310 ATF_TC(readv_heap_end);
311 ATF_TC_HEAD(readv_heap_end, tc)
312 {
313 }
314 ATF_TC_BODY(readv_heap_end, tc)
315 {
316 #define BUF __stack.__buf
317 	struct {
318 		uint8_t padding_l;
319 		struct iovec * __buf;
320 		uint8_t padding_r;
321 	} __stack;
322 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
323 	const size_t __len = 2;
324 	const size_t __idx __unused = __len - 1;
325 
326 	__stack.__buf = malloc(__bufsz);
327 	replace_stdin();
328 
329 	for (size_t __i = 0; __i < 2; __i++) {
330 		__stack.__buf[__i].iov_base = &__stack.padding_l;
331 		__stack.__buf[__i].iov_len = 1;
332 	}
333 
334 	readv(STDIN_FILENO, __stack.__buf, __len);
335 #undef BUF
336 
337 }
338 
339 ATF_TC(readv_heap_after_end);
340 ATF_TC_HEAD(readv_heap_after_end, tc)
341 {
342 }
343 ATF_TC_BODY(readv_heap_after_end, tc)
344 {
345 #define BUF __stack.__buf
346 	struct {
347 		uint8_t padding_l;
348 		struct iovec * __buf;
349 		uint8_t padding_r;
350 	} __stack;
351 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
352 	const size_t __len = 2 + 1;
353 	const size_t __idx __unused = __len - 1;
354 	pid_t __child;
355 	int __status;
356 
357 	__child = fork();
358 	ATF_REQUIRE(__child >= 0);
359 	if (__child > 0)
360 		goto monitor;
361 
362 	/* Child */
363 	disable_coredumps();
364 	__stack.__buf = malloc(__bufsz);
365 	replace_stdin();
366 
367 	for (size_t __i = 0; __i < 2; __i++) {
368 		__stack.__buf[__i].iov_base = &__stack.padding_l;
369 		__stack.__buf[__i].iov_len = 1;
370 	}
371 
372 	readv(STDIN_FILENO, __stack.__buf, __len);
373 	_exit(EX_SOFTWARE);	/* Should have aborted. */
374 
375 monitor:
376 	while (waitpid(__child, &__status, 0) != __child) {
377 		ATF_REQUIRE_EQ(EINTR, errno);
378 	}
379 
380 	if (!WIFSIGNALED(__status)) {
381 		switch (WEXITSTATUS(__status)) {
382 		case EX_SOFTWARE:
383 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
384 			break;
385 		case EX_OSERR:
386 			atf_tc_fail("setrlimit(2) failed");
387 			break;
388 		default:
389 			atf_tc_fail("child exited with status %d",
390 			    WEXITSTATUS(__status));
391 		}
392 	} else {
393 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
394 	}
395 #undef BUF
396 
397 }
398 
399 ATF_TC(readv_iov_before_end);
400 ATF_TC_HEAD(readv_iov_before_end, tc)
401 {
402 }
403 ATF_TC_BODY(readv_iov_before_end, tc)
404 {
405 #define BUF &__stack.__buf
406 	struct {
407 		uint8_t padding_l;
408 		unsigned char __buf[42];
409 		uint8_t padding_r;
410 	} __stack;
411 	const size_t __bufsz __unused = sizeof(__stack.__buf);
412 	const size_t __len = 42 - 1;
413 	const size_t __idx __unused = __len - 1;
414 	struct iovec iov[1];
415 
416 	replace_stdin();
417 
418 	iov[0].iov_base = __stack.__buf;
419 	iov[0].iov_len = __len;
420 
421 	readv(STDIN_FILENO, iov, nitems(iov));
422 #undef BUF
423 
424 }
425 
426 ATF_TC(readv_iov_end);
427 ATF_TC_HEAD(readv_iov_end, tc)
428 {
429 }
430 ATF_TC_BODY(readv_iov_end, tc)
431 {
432 #define BUF &__stack.__buf
433 	struct {
434 		uint8_t padding_l;
435 		unsigned char __buf[42];
436 		uint8_t padding_r;
437 	} __stack;
438 	const size_t __bufsz __unused = sizeof(__stack.__buf);
439 	const size_t __len = 42;
440 	const size_t __idx __unused = __len - 1;
441 	struct iovec iov[1];
442 
443 	replace_stdin();
444 
445 	iov[0].iov_base = __stack.__buf;
446 	iov[0].iov_len = __len;
447 
448 	readv(STDIN_FILENO, iov, nitems(iov));
449 #undef BUF
450 
451 }
452 
453 ATF_TC(readv_iov_heap_before_end);
454 ATF_TC_HEAD(readv_iov_heap_before_end, tc)
455 {
456 }
457 ATF_TC_BODY(readv_iov_heap_before_end, tc)
458 {
459 #define BUF __stack.__buf
460 	struct {
461 		uint8_t padding_l;
462 		unsigned char * __buf;
463 		uint8_t padding_r;
464 	} __stack;
465 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
466 	const size_t __len = 42 - 1;
467 	const size_t __idx __unused = __len - 1;
468 	struct iovec iov[1];
469 
470 	__stack.__buf = malloc(__bufsz);
471 	replace_stdin();
472 
473 	iov[0].iov_base = __stack.__buf;
474 	iov[0].iov_len = __len;
475 
476 	readv(STDIN_FILENO, iov, nitems(iov));
477 #undef BUF
478 
479 }
480 
481 ATF_TC(readv_iov_heap_end);
482 ATF_TC_HEAD(readv_iov_heap_end, tc)
483 {
484 }
485 ATF_TC_BODY(readv_iov_heap_end, tc)
486 {
487 #define BUF __stack.__buf
488 	struct {
489 		uint8_t padding_l;
490 		unsigned char * __buf;
491 		uint8_t padding_r;
492 	} __stack;
493 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
494 	const size_t __len = 42;
495 	const size_t __idx __unused = __len - 1;
496 	struct iovec iov[1];
497 
498 	__stack.__buf = malloc(__bufsz);
499 	replace_stdin();
500 
501 	iov[0].iov_base = __stack.__buf;
502 	iov[0].iov_len = __len;
503 
504 	readv(STDIN_FILENO, iov, nitems(iov));
505 #undef BUF
506 
507 }
508 
509 ATF_TC(readv_iov_heap_after_end);
510 ATF_TC_HEAD(readv_iov_heap_after_end, tc)
511 {
512 }
513 ATF_TC_BODY(readv_iov_heap_after_end, tc)
514 {
515 #define BUF __stack.__buf
516 	struct {
517 		uint8_t padding_l;
518 		unsigned char * __buf;
519 		uint8_t padding_r;
520 	} __stack;
521 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
522 	const size_t __len = 42 + 1;
523 	const size_t __idx __unused = __len - 1;
524 	pid_t __child;
525 	int __status;
526 	struct iovec iov[1];
527 
528 	__child = fork();
529 	ATF_REQUIRE(__child >= 0);
530 	if (__child > 0)
531 		goto monitor;
532 
533 	/* Child */
534 	disable_coredumps();
535 	__stack.__buf = malloc(__bufsz);
536 	replace_stdin();
537 
538 	iov[0].iov_base = __stack.__buf;
539 	iov[0].iov_len = __len;
540 
541 	readv(STDIN_FILENO, iov, nitems(iov));
542 	_exit(EX_SOFTWARE);	/* Should have aborted. */
543 
544 monitor:
545 	while (waitpid(__child, &__status, 0) != __child) {
546 		ATF_REQUIRE_EQ(EINTR, errno);
547 	}
548 
549 	if (!WIFSIGNALED(__status)) {
550 		switch (WEXITSTATUS(__status)) {
551 		case EX_SOFTWARE:
552 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
553 			break;
554 		case EX_OSERR:
555 			atf_tc_fail("setrlimit(2) failed");
556 			break;
557 		default:
558 			atf_tc_fail("child exited with status %d",
559 			    WEXITSTATUS(__status));
560 		}
561 	} else {
562 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
563 	}
564 #undef BUF
565 
566 }
567 
568 ATF_TC(preadv_before_end);
569 ATF_TC_HEAD(preadv_before_end, tc)
570 {
571 }
572 ATF_TC_BODY(preadv_before_end, tc)
573 {
574 #define BUF &__stack.__buf
575 	struct {
576 		uint8_t padding_l;
577 		struct iovec __buf[2];
578 		uint8_t padding_r;
579 	} __stack;
580 	const size_t __bufsz __unused = sizeof(__stack.__buf);
581 	const size_t __len = 2 - 1;
582 	const size_t __idx __unused = __len - 1;
583 
584 	replace_stdin();
585 
586 	for (size_t __i = 0; __i < 2; __i++) {
587 		__stack.__buf[__i].iov_base = &__stack.padding_l;
588 		__stack.__buf[__i].iov_len = 1;
589 	}
590 
591 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
592 #undef BUF
593 
594 }
595 
596 ATF_TC(preadv_end);
597 ATF_TC_HEAD(preadv_end, tc)
598 {
599 }
600 ATF_TC_BODY(preadv_end, tc)
601 {
602 #define BUF &__stack.__buf
603 	struct {
604 		uint8_t padding_l;
605 		struct iovec __buf[2];
606 		uint8_t padding_r;
607 	} __stack;
608 	const size_t __bufsz __unused = sizeof(__stack.__buf);
609 	const size_t __len = 2;
610 	const size_t __idx __unused = __len - 1;
611 
612 	replace_stdin();
613 
614 	for (size_t __i = 0; __i < 2; __i++) {
615 		__stack.__buf[__i].iov_base = &__stack.padding_l;
616 		__stack.__buf[__i].iov_len = 1;
617 	}
618 
619 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
620 #undef BUF
621 
622 }
623 
624 ATF_TC(preadv_after_end);
625 ATF_TC_HEAD(preadv_after_end, tc)
626 {
627 }
628 ATF_TC_BODY(preadv_after_end, tc)
629 {
630 #define BUF &__stack.__buf
631 	struct {
632 		uint8_t padding_l;
633 		struct iovec __buf[2];
634 		uint8_t padding_r;
635 	} __stack;
636 	const size_t __bufsz __unused = sizeof(__stack.__buf);
637 	const size_t __len = 2 + 1;
638 	const size_t __idx __unused = __len - 1;
639 	pid_t __child;
640 	int __status;
641 
642 	__child = fork();
643 	ATF_REQUIRE(__child >= 0);
644 	if (__child > 0)
645 		goto monitor;
646 
647 	/* Child */
648 	disable_coredumps();
649 	replace_stdin();
650 
651 	for (size_t __i = 0; __i < 2; __i++) {
652 		__stack.__buf[__i].iov_base = &__stack.padding_l;
653 		__stack.__buf[__i].iov_len = 1;
654 	}
655 
656 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
657 	_exit(EX_SOFTWARE);	/* Should have aborted. */
658 
659 monitor:
660 	while (waitpid(__child, &__status, 0) != __child) {
661 		ATF_REQUIRE_EQ(EINTR, errno);
662 	}
663 
664 	if (!WIFSIGNALED(__status)) {
665 		switch (WEXITSTATUS(__status)) {
666 		case EX_SOFTWARE:
667 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
668 			break;
669 		case EX_OSERR:
670 			atf_tc_fail("setrlimit(2) failed");
671 			break;
672 		default:
673 			atf_tc_fail("child exited with status %d",
674 			    WEXITSTATUS(__status));
675 		}
676 	} else {
677 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
678 	}
679 #undef BUF
680 
681 }
682 
683 ATF_TC(preadv_heap_before_end);
684 ATF_TC_HEAD(preadv_heap_before_end, tc)
685 {
686 }
687 ATF_TC_BODY(preadv_heap_before_end, tc)
688 {
689 #define BUF __stack.__buf
690 	struct {
691 		uint8_t padding_l;
692 		struct iovec * __buf;
693 		uint8_t padding_r;
694 	} __stack;
695 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
696 	const size_t __len = 2 - 1;
697 	const size_t __idx __unused = __len - 1;
698 
699 	__stack.__buf = malloc(__bufsz);
700 	replace_stdin();
701 
702 	for (size_t __i = 0; __i < 2; __i++) {
703 		__stack.__buf[__i].iov_base = &__stack.padding_l;
704 		__stack.__buf[__i].iov_len = 1;
705 	}
706 
707 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
708 #undef BUF
709 
710 }
711 
712 ATF_TC(preadv_heap_end);
713 ATF_TC_HEAD(preadv_heap_end, tc)
714 {
715 }
716 ATF_TC_BODY(preadv_heap_end, tc)
717 {
718 #define BUF __stack.__buf
719 	struct {
720 		uint8_t padding_l;
721 		struct iovec * __buf;
722 		uint8_t padding_r;
723 	} __stack;
724 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
725 	const size_t __len = 2;
726 	const size_t __idx __unused = __len - 1;
727 
728 	__stack.__buf = malloc(__bufsz);
729 	replace_stdin();
730 
731 	for (size_t __i = 0; __i < 2; __i++) {
732 		__stack.__buf[__i].iov_base = &__stack.padding_l;
733 		__stack.__buf[__i].iov_len = 1;
734 	}
735 
736 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
737 #undef BUF
738 
739 }
740 
741 ATF_TC(preadv_heap_after_end);
742 ATF_TC_HEAD(preadv_heap_after_end, tc)
743 {
744 }
745 ATF_TC_BODY(preadv_heap_after_end, tc)
746 {
747 #define BUF __stack.__buf
748 	struct {
749 		uint8_t padding_l;
750 		struct iovec * __buf;
751 		uint8_t padding_r;
752 	} __stack;
753 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
754 	const size_t __len = 2 + 1;
755 	const size_t __idx __unused = __len - 1;
756 	pid_t __child;
757 	int __status;
758 
759 	__child = fork();
760 	ATF_REQUIRE(__child >= 0);
761 	if (__child > 0)
762 		goto monitor;
763 
764 	/* Child */
765 	disable_coredumps();
766 	__stack.__buf = malloc(__bufsz);
767 	replace_stdin();
768 
769 	for (size_t __i = 0; __i < 2; __i++) {
770 		__stack.__buf[__i].iov_base = &__stack.padding_l;
771 		__stack.__buf[__i].iov_len = 1;
772 	}
773 
774 	preadv(STDIN_FILENO, __stack.__buf, __len, 0);
775 	_exit(EX_SOFTWARE);	/* Should have aborted. */
776 
777 monitor:
778 	while (waitpid(__child, &__status, 0) != __child) {
779 		ATF_REQUIRE_EQ(EINTR, errno);
780 	}
781 
782 	if (!WIFSIGNALED(__status)) {
783 		switch (WEXITSTATUS(__status)) {
784 		case EX_SOFTWARE:
785 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
786 			break;
787 		case EX_OSERR:
788 			atf_tc_fail("setrlimit(2) failed");
789 			break;
790 		default:
791 			atf_tc_fail("child exited with status %d",
792 			    WEXITSTATUS(__status));
793 		}
794 	} else {
795 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
796 	}
797 #undef BUF
798 
799 }
800 
801 ATF_TC(preadv_iov_before_end);
802 ATF_TC_HEAD(preadv_iov_before_end, tc)
803 {
804 }
805 ATF_TC_BODY(preadv_iov_before_end, tc)
806 {
807 #define BUF &__stack.__buf
808 	struct {
809 		uint8_t padding_l;
810 		unsigned char __buf[42];
811 		uint8_t padding_r;
812 	} __stack;
813 	const size_t __bufsz __unused = sizeof(__stack.__buf);
814 	const size_t __len = 42 - 1;
815 	const size_t __idx __unused = __len - 1;
816 	struct iovec iov[1];
817 
818 	replace_stdin();
819 
820 	iov[0].iov_base = __stack.__buf;
821 	iov[0].iov_len = __len;
822 
823 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
824 #undef BUF
825 
826 }
827 
828 ATF_TC(preadv_iov_end);
829 ATF_TC_HEAD(preadv_iov_end, tc)
830 {
831 }
832 ATF_TC_BODY(preadv_iov_end, tc)
833 {
834 #define BUF &__stack.__buf
835 	struct {
836 		uint8_t padding_l;
837 		unsigned char __buf[42];
838 		uint8_t padding_r;
839 	} __stack;
840 	const size_t __bufsz __unused = sizeof(__stack.__buf);
841 	const size_t __len = 42;
842 	const size_t __idx __unused = __len - 1;
843 	struct iovec iov[1];
844 
845 	replace_stdin();
846 
847 	iov[0].iov_base = __stack.__buf;
848 	iov[0].iov_len = __len;
849 
850 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
851 #undef BUF
852 
853 }
854 
855 ATF_TC(preadv_iov_heap_before_end);
856 ATF_TC_HEAD(preadv_iov_heap_before_end, tc)
857 {
858 }
859 ATF_TC_BODY(preadv_iov_heap_before_end, tc)
860 {
861 #define BUF __stack.__buf
862 	struct {
863 		uint8_t padding_l;
864 		unsigned char * __buf;
865 		uint8_t padding_r;
866 	} __stack;
867 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
868 	const size_t __len = 42 - 1;
869 	const size_t __idx __unused = __len - 1;
870 	struct iovec iov[1];
871 
872 	__stack.__buf = malloc(__bufsz);
873 	replace_stdin();
874 
875 	iov[0].iov_base = __stack.__buf;
876 	iov[0].iov_len = __len;
877 
878 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
879 #undef BUF
880 
881 }
882 
883 ATF_TC(preadv_iov_heap_end);
884 ATF_TC_HEAD(preadv_iov_heap_end, tc)
885 {
886 }
887 ATF_TC_BODY(preadv_iov_heap_end, tc)
888 {
889 #define BUF __stack.__buf
890 	struct {
891 		uint8_t padding_l;
892 		unsigned char * __buf;
893 		uint8_t padding_r;
894 	} __stack;
895 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
896 	const size_t __len = 42;
897 	const size_t __idx __unused = __len - 1;
898 	struct iovec iov[1];
899 
900 	__stack.__buf = malloc(__bufsz);
901 	replace_stdin();
902 
903 	iov[0].iov_base = __stack.__buf;
904 	iov[0].iov_len = __len;
905 
906 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
907 #undef BUF
908 
909 }
910 
911 ATF_TC(preadv_iov_heap_after_end);
912 ATF_TC_HEAD(preadv_iov_heap_after_end, tc)
913 {
914 }
915 ATF_TC_BODY(preadv_iov_heap_after_end, tc)
916 {
917 #define BUF __stack.__buf
918 	struct {
919 		uint8_t padding_l;
920 		unsigned char * __buf;
921 		uint8_t padding_r;
922 	} __stack;
923 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
924 	const size_t __len = 42 + 1;
925 	const size_t __idx __unused = __len - 1;
926 	pid_t __child;
927 	int __status;
928 	struct iovec iov[1];
929 
930 	__child = fork();
931 	ATF_REQUIRE(__child >= 0);
932 	if (__child > 0)
933 		goto monitor;
934 
935 	/* Child */
936 	disable_coredumps();
937 	__stack.__buf = malloc(__bufsz);
938 	replace_stdin();
939 
940 	iov[0].iov_base = __stack.__buf;
941 	iov[0].iov_len = __len;
942 
943 	preadv(STDIN_FILENO, iov, nitems(iov), 0);
944 	_exit(EX_SOFTWARE);	/* Should have aborted. */
945 
946 monitor:
947 	while (waitpid(__child, &__status, 0) != __child) {
948 		ATF_REQUIRE_EQ(EINTR, errno);
949 	}
950 
951 	if (!WIFSIGNALED(__status)) {
952 		switch (WEXITSTATUS(__status)) {
953 		case EX_SOFTWARE:
954 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
955 			break;
956 		case EX_OSERR:
957 			atf_tc_fail("setrlimit(2) failed");
958 			break;
959 		default:
960 			atf_tc_fail("child exited with status %d",
961 			    WEXITSTATUS(__status));
962 		}
963 	} else {
964 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
965 	}
966 #undef BUF
967 
968 }
969 
970 ATF_TP_ADD_TCS(tp)
971 {
972 	ATF_TP_ADD_TC(tp, readv_before_end);
973 	ATF_TP_ADD_TC(tp, readv_end);
974 	ATF_TP_ADD_TC(tp, readv_after_end);
975 	ATF_TP_ADD_TC(tp, readv_heap_before_end);
976 	ATF_TP_ADD_TC(tp, readv_heap_end);
977 	ATF_TP_ADD_TC(tp, readv_heap_after_end);
978 	ATF_TP_ADD_TC(tp, readv_iov_before_end);
979 	ATF_TP_ADD_TC(tp, readv_iov_end);
980 	ATF_TP_ADD_TC(tp, readv_iov_heap_before_end);
981 	ATF_TP_ADD_TC(tp, readv_iov_heap_end);
982 	ATF_TP_ADD_TC(tp, readv_iov_heap_after_end);
983 	ATF_TP_ADD_TC(tp, preadv_before_end);
984 	ATF_TP_ADD_TC(tp, preadv_end);
985 	ATF_TP_ADD_TC(tp, preadv_after_end);
986 	ATF_TP_ADD_TC(tp, preadv_heap_before_end);
987 	ATF_TP_ADD_TC(tp, preadv_heap_end);
988 	ATF_TP_ADD_TC(tp, preadv_heap_after_end);
989 	ATF_TP_ADD_TC(tp, preadv_iov_before_end);
990 	ATF_TP_ADD_TC(tp, preadv_iov_end);
991 	ATF_TP_ADD_TC(tp, preadv_iov_heap_before_end);
992 	ATF_TP_ADD_TC(tp, preadv_iov_heap_end);
993 	ATF_TP_ADD_TC(tp, preadv_iov_heap_after_end);
994 	return (atf_no_error());
995 }
996