xref: /freebsd/lib/libc/tests/secure/fortify_select_test.c (revision 22178cb29f03a3b7bf919f3605e0cd5d6b18fa0a)
1 /* @generated by `generate-fortify-tests.lua "select"` */
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(FD_SET_before_end);
ATF_TC_HEAD(FD_SET_before_end,tc)167 ATF_TC_HEAD(FD_SET_before_end, tc)
168 {
169 }
ATF_TC_BODY(FD_SET_before_end,tc)170 ATF_TC_BODY(FD_SET_before_end, tc)
171 {
172 #define BUF &__stack.__buf
173 	struct {
174 		uint8_t padding_l;
175 		fd_set __buf;
176 		uint8_t padding_r;
177 	} __stack;
178 	const size_t __bufsz __unused = sizeof(__stack.__buf);
179 	const size_t __len = FD_SETSIZE - 1;
180 	const size_t __idx __unused = __len - 1;
181 
182 	FD_SET(__idx, &__stack.__buf);
183 #undef BUF
184 
185 }
186 
187 ATF_TC(FD_SET_end);
ATF_TC_HEAD(FD_SET_end,tc)188 ATF_TC_HEAD(FD_SET_end, tc)
189 {
190 }
ATF_TC_BODY(FD_SET_end,tc)191 ATF_TC_BODY(FD_SET_end, tc)
192 {
193 #define BUF &__stack.__buf
194 	struct {
195 		uint8_t padding_l;
196 		fd_set __buf;
197 		uint8_t padding_r;
198 	} __stack;
199 	const size_t __bufsz __unused = sizeof(__stack.__buf);
200 	const size_t __len = FD_SETSIZE;
201 	const size_t __idx __unused = __len - 1;
202 
203 	FD_SET(__idx, &__stack.__buf);
204 #undef BUF
205 
206 }
207 
208 ATF_TC(FD_SET_after_end);
ATF_TC_HEAD(FD_SET_after_end,tc)209 ATF_TC_HEAD(FD_SET_after_end, tc)
210 {
211 }
ATF_TC_BODY(FD_SET_after_end,tc)212 ATF_TC_BODY(FD_SET_after_end, tc)
213 {
214 #define BUF &__stack.__buf
215 	struct {
216 		uint8_t padding_l;
217 		fd_set __buf;
218 		uint8_t padding_r;
219 	} __stack;
220 	const size_t __bufsz __unused = sizeof(__stack.__buf);
221 	const size_t __len = FD_SETSIZE + 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 	FD_SET(__idx, &__stack.__buf);
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(FD_SET_heap_before_end);
ATF_TC_HEAD(FD_SET_heap_before_end,tc)261 ATF_TC_HEAD(FD_SET_heap_before_end, tc)
262 {
263 }
ATF_TC_BODY(FD_SET_heap_before_end,tc)264 ATF_TC_BODY(FD_SET_heap_before_end, tc)
265 {
266 #define BUF __stack.__buf
267 	struct {
268 		uint8_t padding_l;
269 		fd_set * __buf;
270 		uint8_t padding_r;
271 	} __stack;
272 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
273 	const size_t __len = FD_SETSIZE - 1;
274 	const size_t __idx __unused = __len - 1;
275 
276 	__stack.__buf = malloc(__bufsz);
277 
278 	FD_SET(__idx, __stack.__buf);
279 #undef BUF
280 
281 }
282 
283 ATF_TC(FD_SET_heap_end);
ATF_TC_HEAD(FD_SET_heap_end,tc)284 ATF_TC_HEAD(FD_SET_heap_end, tc)
285 {
286 }
ATF_TC_BODY(FD_SET_heap_end,tc)287 ATF_TC_BODY(FD_SET_heap_end, tc)
288 {
289 #define BUF __stack.__buf
290 	struct {
291 		uint8_t padding_l;
292 		fd_set * __buf;
293 		uint8_t padding_r;
294 	} __stack;
295 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
296 	const size_t __len = FD_SETSIZE;
297 	const size_t __idx __unused = __len - 1;
298 
299 	__stack.__buf = malloc(__bufsz);
300 
301 	FD_SET(__idx, __stack.__buf);
302 #undef BUF
303 
304 }
305 
306 ATF_TC(FD_SET_heap_after_end);
ATF_TC_HEAD(FD_SET_heap_after_end,tc)307 ATF_TC_HEAD(FD_SET_heap_after_end, tc)
308 {
309 }
ATF_TC_BODY(FD_SET_heap_after_end,tc)310 ATF_TC_BODY(FD_SET_heap_after_end, tc)
311 {
312 #define BUF __stack.__buf
313 	struct {
314 		uint8_t padding_l;
315 		fd_set * __buf;
316 		uint8_t padding_r;
317 	} __stack;
318 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
319 	const size_t __len = FD_SETSIZE + 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 	FD_SET(__idx, __stack.__buf);
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(FD_CLR_before_end);
ATF_TC_HEAD(FD_CLR_before_end,tc)361 ATF_TC_HEAD(FD_CLR_before_end, tc)
362 {
363 }
ATF_TC_BODY(FD_CLR_before_end,tc)364 ATF_TC_BODY(FD_CLR_before_end, tc)
365 {
366 #define BUF &__stack.__buf
367 	struct {
368 		uint8_t padding_l;
369 		fd_set __buf;
370 		uint8_t padding_r;
371 	} __stack;
372 	const size_t __bufsz __unused = sizeof(__stack.__buf);
373 	const size_t __len = FD_SETSIZE - 1;
374 	const size_t __idx __unused = __len - 1;
375 
376 	FD_CLR(__idx, &__stack.__buf);
377 #undef BUF
378 
379 }
380 
381 ATF_TC(FD_CLR_end);
ATF_TC_HEAD(FD_CLR_end,tc)382 ATF_TC_HEAD(FD_CLR_end, tc)
383 {
384 }
ATF_TC_BODY(FD_CLR_end,tc)385 ATF_TC_BODY(FD_CLR_end, tc)
386 {
387 #define BUF &__stack.__buf
388 	struct {
389 		uint8_t padding_l;
390 		fd_set __buf;
391 		uint8_t padding_r;
392 	} __stack;
393 	const size_t __bufsz __unused = sizeof(__stack.__buf);
394 	const size_t __len = FD_SETSIZE;
395 	const size_t __idx __unused = __len - 1;
396 
397 	FD_CLR(__idx, &__stack.__buf);
398 #undef BUF
399 
400 }
401 
402 ATF_TC(FD_CLR_after_end);
ATF_TC_HEAD(FD_CLR_after_end,tc)403 ATF_TC_HEAD(FD_CLR_after_end, tc)
404 {
405 }
ATF_TC_BODY(FD_CLR_after_end,tc)406 ATF_TC_BODY(FD_CLR_after_end, tc)
407 {
408 #define BUF &__stack.__buf
409 	struct {
410 		uint8_t padding_l;
411 		fd_set __buf;
412 		uint8_t padding_r;
413 	} __stack;
414 	const size_t __bufsz __unused = sizeof(__stack.__buf);
415 	const size_t __len = FD_SETSIZE + 1;
416 	const size_t __idx __unused = __len - 1;
417 	pid_t __child;
418 	int __status;
419 
420 	__child = fork();
421 	ATF_REQUIRE(__child >= 0);
422 	if (__child > 0)
423 		goto monitor;
424 
425 	/* Child */
426 	disable_coredumps();
427 	FD_CLR(__idx, &__stack.__buf);
428 	_exit(EX_SOFTWARE);	/* Should have aborted. */
429 
430 monitor:
431 	while (waitpid(__child, &__status, 0) != __child) {
432 		ATF_REQUIRE_EQ(EINTR, errno);
433 	}
434 
435 	if (!WIFSIGNALED(__status)) {
436 		switch (WEXITSTATUS(__status)) {
437 		case EX_SOFTWARE:
438 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
439 			break;
440 		case EX_OSERR:
441 			atf_tc_fail("setrlimit(2) failed");
442 			break;
443 		default:
444 			atf_tc_fail("child exited with status %d",
445 			    WEXITSTATUS(__status));
446 		}
447 	} else {
448 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
449 	}
450 #undef BUF
451 
452 }
453 
454 ATF_TC(FD_CLR_heap_before_end);
ATF_TC_HEAD(FD_CLR_heap_before_end,tc)455 ATF_TC_HEAD(FD_CLR_heap_before_end, tc)
456 {
457 }
ATF_TC_BODY(FD_CLR_heap_before_end,tc)458 ATF_TC_BODY(FD_CLR_heap_before_end, tc)
459 {
460 #define BUF __stack.__buf
461 	struct {
462 		uint8_t padding_l;
463 		fd_set * __buf;
464 		uint8_t padding_r;
465 	} __stack;
466 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
467 	const size_t __len = FD_SETSIZE - 1;
468 	const size_t __idx __unused = __len - 1;
469 
470 	__stack.__buf = malloc(__bufsz);
471 
472 	FD_CLR(__idx, __stack.__buf);
473 #undef BUF
474 
475 }
476 
477 ATF_TC(FD_CLR_heap_end);
ATF_TC_HEAD(FD_CLR_heap_end,tc)478 ATF_TC_HEAD(FD_CLR_heap_end, tc)
479 {
480 }
ATF_TC_BODY(FD_CLR_heap_end,tc)481 ATF_TC_BODY(FD_CLR_heap_end, tc)
482 {
483 #define BUF __stack.__buf
484 	struct {
485 		uint8_t padding_l;
486 		fd_set * __buf;
487 		uint8_t padding_r;
488 	} __stack;
489 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
490 	const size_t __len = FD_SETSIZE;
491 	const size_t __idx __unused = __len - 1;
492 
493 	__stack.__buf = malloc(__bufsz);
494 
495 	FD_CLR(__idx, __stack.__buf);
496 #undef BUF
497 
498 }
499 
500 ATF_TC(FD_CLR_heap_after_end);
ATF_TC_HEAD(FD_CLR_heap_after_end,tc)501 ATF_TC_HEAD(FD_CLR_heap_after_end, tc)
502 {
503 }
ATF_TC_BODY(FD_CLR_heap_after_end,tc)504 ATF_TC_BODY(FD_CLR_heap_after_end, tc)
505 {
506 #define BUF __stack.__buf
507 	struct {
508 		uint8_t padding_l;
509 		fd_set * __buf;
510 		uint8_t padding_r;
511 	} __stack;
512 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
513 	const size_t __len = FD_SETSIZE + 1;
514 	const size_t __idx __unused = __len - 1;
515 	pid_t __child;
516 	int __status;
517 
518 	__child = fork();
519 	ATF_REQUIRE(__child >= 0);
520 	if (__child > 0)
521 		goto monitor;
522 
523 	/* Child */
524 	disable_coredumps();
525 	__stack.__buf = malloc(__bufsz);
526 
527 	FD_CLR(__idx, __stack.__buf);
528 	_exit(EX_SOFTWARE);	/* Should have aborted. */
529 
530 monitor:
531 	while (waitpid(__child, &__status, 0) != __child) {
532 		ATF_REQUIRE_EQ(EINTR, errno);
533 	}
534 
535 	if (!WIFSIGNALED(__status)) {
536 		switch (WEXITSTATUS(__status)) {
537 		case EX_SOFTWARE:
538 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
539 			break;
540 		case EX_OSERR:
541 			atf_tc_fail("setrlimit(2) failed");
542 			break;
543 		default:
544 			atf_tc_fail("child exited with status %d",
545 			    WEXITSTATUS(__status));
546 		}
547 	} else {
548 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
549 	}
550 #undef BUF
551 
552 }
553 
554 ATF_TC(FD_ISSET_before_end);
ATF_TC_HEAD(FD_ISSET_before_end,tc)555 ATF_TC_HEAD(FD_ISSET_before_end, tc)
556 {
557 }
ATF_TC_BODY(FD_ISSET_before_end,tc)558 ATF_TC_BODY(FD_ISSET_before_end, tc)
559 {
560 #define BUF &__stack.__buf
561 	struct {
562 		uint8_t padding_l;
563 		fd_set __buf;
564 		uint8_t padding_r;
565 	} __stack;
566 	const size_t __bufsz __unused = sizeof(__stack.__buf);
567 	const size_t __len = FD_SETSIZE - 1;
568 	const size_t __idx __unused = __len - 1;
569 
570 	FD_ISSET(__idx, &__stack.__buf);
571 #undef BUF
572 
573 }
574 
575 ATF_TC(FD_ISSET_end);
ATF_TC_HEAD(FD_ISSET_end,tc)576 ATF_TC_HEAD(FD_ISSET_end, tc)
577 {
578 }
ATF_TC_BODY(FD_ISSET_end,tc)579 ATF_TC_BODY(FD_ISSET_end, tc)
580 {
581 #define BUF &__stack.__buf
582 	struct {
583 		uint8_t padding_l;
584 		fd_set __buf;
585 		uint8_t padding_r;
586 	} __stack;
587 	const size_t __bufsz __unused = sizeof(__stack.__buf);
588 	const size_t __len = FD_SETSIZE;
589 	const size_t __idx __unused = __len - 1;
590 
591 	FD_ISSET(__idx, &__stack.__buf);
592 #undef BUF
593 
594 }
595 
596 ATF_TC(FD_ISSET_after_end);
ATF_TC_HEAD(FD_ISSET_after_end,tc)597 ATF_TC_HEAD(FD_ISSET_after_end, tc)
598 {
599 }
ATF_TC_BODY(FD_ISSET_after_end,tc)600 ATF_TC_BODY(FD_ISSET_after_end, tc)
601 {
602 #define BUF &__stack.__buf
603 	struct {
604 		uint8_t padding_l;
605 		fd_set __buf;
606 		uint8_t padding_r;
607 	} __stack;
608 	const size_t __bufsz __unused = sizeof(__stack.__buf);
609 	const size_t __len = FD_SETSIZE + 1;
610 	const size_t __idx __unused = __len - 1;
611 	pid_t __child;
612 	int __status;
613 
614 	__child = fork();
615 	ATF_REQUIRE(__child >= 0);
616 	if (__child > 0)
617 		goto monitor;
618 
619 	/* Child */
620 	disable_coredumps();
621 	FD_ISSET(__idx, &__stack.__buf);
622 	_exit(EX_SOFTWARE);	/* Should have aborted. */
623 
624 monitor:
625 	while (waitpid(__child, &__status, 0) != __child) {
626 		ATF_REQUIRE_EQ(EINTR, errno);
627 	}
628 
629 	if (!WIFSIGNALED(__status)) {
630 		switch (WEXITSTATUS(__status)) {
631 		case EX_SOFTWARE:
632 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
633 			break;
634 		case EX_OSERR:
635 			atf_tc_fail("setrlimit(2) failed");
636 			break;
637 		default:
638 			atf_tc_fail("child exited with status %d",
639 			    WEXITSTATUS(__status));
640 		}
641 	} else {
642 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
643 	}
644 #undef BUF
645 
646 }
647 
648 ATF_TC(FD_ISSET_heap_before_end);
ATF_TC_HEAD(FD_ISSET_heap_before_end,tc)649 ATF_TC_HEAD(FD_ISSET_heap_before_end, tc)
650 {
651 }
ATF_TC_BODY(FD_ISSET_heap_before_end,tc)652 ATF_TC_BODY(FD_ISSET_heap_before_end, tc)
653 {
654 #define BUF __stack.__buf
655 	struct {
656 		uint8_t padding_l;
657 		fd_set * __buf;
658 		uint8_t padding_r;
659 	} __stack;
660 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
661 	const size_t __len = FD_SETSIZE - 1;
662 	const size_t __idx __unused = __len - 1;
663 
664 	__stack.__buf = malloc(__bufsz);
665 
666 	FD_ISSET(__idx, __stack.__buf);
667 #undef BUF
668 
669 }
670 
671 ATF_TC(FD_ISSET_heap_end);
ATF_TC_HEAD(FD_ISSET_heap_end,tc)672 ATF_TC_HEAD(FD_ISSET_heap_end, tc)
673 {
674 }
ATF_TC_BODY(FD_ISSET_heap_end,tc)675 ATF_TC_BODY(FD_ISSET_heap_end, tc)
676 {
677 #define BUF __stack.__buf
678 	struct {
679 		uint8_t padding_l;
680 		fd_set * __buf;
681 		uint8_t padding_r;
682 	} __stack;
683 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
684 	const size_t __len = FD_SETSIZE;
685 	const size_t __idx __unused = __len - 1;
686 
687 	__stack.__buf = malloc(__bufsz);
688 
689 	FD_ISSET(__idx, __stack.__buf);
690 #undef BUF
691 
692 }
693 
694 ATF_TC(FD_ISSET_heap_after_end);
ATF_TC_HEAD(FD_ISSET_heap_after_end,tc)695 ATF_TC_HEAD(FD_ISSET_heap_after_end, tc)
696 {
697 }
ATF_TC_BODY(FD_ISSET_heap_after_end,tc)698 ATF_TC_BODY(FD_ISSET_heap_after_end, tc)
699 {
700 #define BUF __stack.__buf
701 	struct {
702 		uint8_t padding_l;
703 		fd_set * __buf;
704 		uint8_t padding_r;
705 	} __stack;
706 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
707 	const size_t __len = FD_SETSIZE + 1;
708 	const size_t __idx __unused = __len - 1;
709 	pid_t __child;
710 	int __status;
711 
712 	__child = fork();
713 	ATF_REQUIRE(__child >= 0);
714 	if (__child > 0)
715 		goto monitor;
716 
717 	/* Child */
718 	disable_coredumps();
719 	__stack.__buf = malloc(__bufsz);
720 
721 	FD_ISSET(__idx, __stack.__buf);
722 	_exit(EX_SOFTWARE);	/* Should have aborted. */
723 
724 monitor:
725 	while (waitpid(__child, &__status, 0) != __child) {
726 		ATF_REQUIRE_EQ(EINTR, errno);
727 	}
728 
729 	if (!WIFSIGNALED(__status)) {
730 		switch (WEXITSTATUS(__status)) {
731 		case EX_SOFTWARE:
732 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
733 			break;
734 		case EX_OSERR:
735 			atf_tc_fail("setrlimit(2) failed");
736 			break;
737 		default:
738 			atf_tc_fail("child exited with status %d",
739 			    WEXITSTATUS(__status));
740 		}
741 	} else {
742 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
743 	}
744 #undef BUF
745 
746 }
747 
ATF_TP_ADD_TCS(tp)748 ATF_TP_ADD_TCS(tp)
749 {
750 	ATF_TP_ADD_TC(tp, FD_SET_before_end);
751 	ATF_TP_ADD_TC(tp, FD_SET_end);
752 	ATF_TP_ADD_TC(tp, FD_SET_after_end);
753 	ATF_TP_ADD_TC(tp, FD_SET_heap_before_end);
754 	ATF_TP_ADD_TC(tp, FD_SET_heap_end);
755 	ATF_TP_ADD_TC(tp, FD_SET_heap_after_end);
756 	ATF_TP_ADD_TC(tp, FD_CLR_before_end);
757 	ATF_TP_ADD_TC(tp, FD_CLR_end);
758 	ATF_TP_ADD_TC(tp, FD_CLR_after_end);
759 	ATF_TP_ADD_TC(tp, FD_CLR_heap_before_end);
760 	ATF_TP_ADD_TC(tp, FD_CLR_heap_end);
761 	ATF_TP_ADD_TC(tp, FD_CLR_heap_after_end);
762 	ATF_TP_ADD_TC(tp, FD_ISSET_before_end);
763 	ATF_TP_ADD_TC(tp, FD_ISSET_end);
764 	ATF_TP_ADD_TC(tp, FD_ISSET_after_end);
765 	ATF_TP_ADD_TC(tp, FD_ISSET_heap_before_end);
766 	ATF_TP_ADD_TC(tp, FD_ISSET_heap_end);
767 	ATF_TP_ADD_TC(tp, FD_ISSET_heap_after_end);
768 	return (atf_no_error());
769 }
770