xref: /freebsd/lib/libc/tests/secure/fortify_select_test.c (revision 2aba0eea3ffffce74f9d8df20e0aaf49ea6d76c3)
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/random.h>
8 #include <sys/resource.h>
9 #include <sys/select.h>
10 #include <sys/time.h>
11 #include <sys/uio.h>
12 #include <sys/wait.h>
13 #include <dirent.h>
14 #include <errno.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <poll.h>
18 #include <signal.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <strings.h>
23 #include <sysexits.h>
24 #include <unistd.h>
25 #include <wchar.h>
26 #include <atf-c.h>
27 
28 static FILE * __unused
29 new_fp(size_t __len)
30 {
31 	static char fpbuf[LINE_MAX];
32 	FILE *fp;
33 
34 	ATF_REQUIRE(__len <= sizeof(fpbuf));
35 
36 	memset(fpbuf, 'A', sizeof(fpbuf) - 1);
37 	fpbuf[sizeof(fpbuf) - 1] = '\0';
38 
39 	fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
40 	ATF_REQUIRE(fp != NULL);
41 
42 	return (fp);
43 }
44 
45 /*
46  * Create a new symlink to use for readlink(2) style tests, we'll just use a
47  * random target name to have something interesting to look at.
48  */
49 static const char * __unused
50 new_symlink(size_t __len)
51 {
52 	static const char linkname[] = "link";
53 	char target[MAXNAMLEN];
54 	int error;
55 
56 	ATF_REQUIRE(__len <= sizeof(target));
57 
58 	arc4random_buf(target, sizeof(target));
59 
60 	error = unlink(linkname);
61 	ATF_REQUIRE(error == 0 || errno == ENOENT);
62 
63 	error = symlink(target, linkname);
64 	ATF_REQUIRE(error == 0);
65 
66 	return (linkname);
67 }
68 
69 /*
70  * Constructs a tmpfile that we can use for testing read(2) and friends.
71  */
72 static int __unused
73 new_tmpfile(void)
74 {
75 	char buf[1024];
76 	ssize_t rv;
77 	size_t written;
78 	int fd;
79 
80 	fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
81 	ATF_REQUIRE(fd >= 0);
82 
83 	written = 0;
84 	while (written < TMPFILE_SIZE) {
85 		rv = write(fd, buf, sizeof(buf));
86 		ATF_REQUIRE(rv > 0);
87 
88 		written += rv;
89 	}
90 
91 	ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
92 	return (fd);
93 }
94 
95 static void
96 disable_coredumps(void)
97 {
98 	struct rlimit rl = { 0 };
99 
100 	if (setrlimit(RLIMIT_CORE, &rl) == -1)
101 		_exit(EX_OSERR);
102 }
103 
104 /*
105  * Replaces stdin with a file that we can actually read from, for tests where
106  * we want a FILE * or fd that we can get data from.
107  */
108 static void __unused
109 replace_stdin(void)
110 {
111 	int fd;
112 
113 	fd = new_tmpfile();
114 
115 	(void)dup2(fd, STDIN_FILENO);
116 	if (fd != STDIN_FILENO)
117 		close(fd);
118 }
119 
120 ATF_TC_WITHOUT_HEAD(FD_SET_before_end);
121 ATF_TC_BODY(FD_SET_before_end, tc)
122 {
123 #define BUF &__stack.__buf
124 	struct {
125 		uint8_t padding_l;
126 		fd_set __buf;
127 		uint8_t padding_r;
128 	} __stack;
129 	const size_t __bufsz __unused = sizeof(__stack.__buf);
130 	const size_t __len = FD_SETSIZE - 1;
131 	const size_t __idx __unused = __len - 1;
132 
133 	FD_SET(__idx, &__stack.__buf);
134 #undef BUF
135 
136 }
137 
138 ATF_TC_WITHOUT_HEAD(FD_SET_end);
139 ATF_TC_BODY(FD_SET_end, tc)
140 {
141 #define BUF &__stack.__buf
142 	struct {
143 		uint8_t padding_l;
144 		fd_set __buf;
145 		uint8_t padding_r;
146 	} __stack;
147 	const size_t __bufsz __unused = sizeof(__stack.__buf);
148 	const size_t __len = FD_SETSIZE;
149 	const size_t __idx __unused = __len - 1;
150 
151 	FD_SET(__idx, &__stack.__buf);
152 #undef BUF
153 
154 }
155 
156 ATF_TC_WITHOUT_HEAD(FD_SET_after_end);
157 ATF_TC_BODY(FD_SET_after_end, tc)
158 {
159 #define BUF &__stack.__buf
160 	struct {
161 		uint8_t padding_l;
162 		fd_set __buf;
163 		uint8_t padding_r;
164 	} __stack;
165 	const size_t __bufsz __unused = sizeof(__stack.__buf);
166 	const size_t __len = FD_SETSIZE + 1;
167 	const size_t __idx __unused = __len - 1;
168 	pid_t __child;
169 	int __status;
170 
171 	__child = fork();
172 	ATF_REQUIRE(__child >= 0);
173 	if (__child > 0)
174 		goto monitor;
175 
176 	/* Child */
177 	disable_coredumps();
178 	FD_SET(__idx, &__stack.__buf);
179 	_exit(EX_SOFTWARE);	/* Should have aborted. */
180 
181 monitor:
182 	while (waitpid(__child, &__status, 0) != __child) {
183 		ATF_REQUIRE_EQ(EINTR, errno);
184 	}
185 
186 	if (!WIFSIGNALED(__status)) {
187 		switch (WEXITSTATUS(__status)) {
188 		case EX_SOFTWARE:
189 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
190 			break;
191 		case EX_OSERR:
192 			atf_tc_fail("setrlimit(2) failed");
193 			break;
194 		default:
195 			atf_tc_fail("child exited with status %d",
196 			    WEXITSTATUS(__status));
197 		}
198 	} else {
199 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
200 	}
201 #undef BUF
202 
203 }
204 
205 ATF_TC_WITHOUT_HEAD(FD_SET_heap_before_end);
206 ATF_TC_BODY(FD_SET_heap_before_end, tc)
207 {
208 #define BUF __stack.__buf
209 	struct {
210 		uint8_t padding_l;
211 		fd_set * __buf;
212 		uint8_t padding_r;
213 	} __stack;
214 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
215 	const size_t __len = FD_SETSIZE - 1;
216 	const size_t __idx __unused = __len - 1;
217 
218 	__stack.__buf = malloc(__bufsz);
219 
220 	FD_SET(__idx, __stack.__buf);
221 #undef BUF
222 
223 }
224 
225 ATF_TC_WITHOUT_HEAD(FD_SET_heap_end);
226 ATF_TC_BODY(FD_SET_heap_end, tc)
227 {
228 #define BUF __stack.__buf
229 	struct {
230 		uint8_t padding_l;
231 		fd_set * __buf;
232 		uint8_t padding_r;
233 	} __stack;
234 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
235 	const size_t __len = FD_SETSIZE;
236 	const size_t __idx __unused = __len - 1;
237 
238 	__stack.__buf = malloc(__bufsz);
239 
240 	FD_SET(__idx, __stack.__buf);
241 #undef BUF
242 
243 }
244 
245 ATF_TC_WITHOUT_HEAD(FD_SET_heap_after_end);
246 ATF_TC_BODY(FD_SET_heap_after_end, tc)
247 {
248 #define BUF __stack.__buf
249 	struct {
250 		uint8_t padding_l;
251 		fd_set * __buf;
252 		uint8_t padding_r;
253 	} __stack;
254 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
255 	const size_t __len = FD_SETSIZE + 1;
256 	const size_t __idx __unused = __len - 1;
257 	pid_t __child;
258 	int __status;
259 
260 	__child = fork();
261 	ATF_REQUIRE(__child >= 0);
262 	if (__child > 0)
263 		goto monitor;
264 
265 	/* Child */
266 	disable_coredumps();
267 	__stack.__buf = malloc(__bufsz);
268 
269 	FD_SET(__idx, __stack.__buf);
270 	_exit(EX_SOFTWARE);	/* Should have aborted. */
271 
272 monitor:
273 	while (waitpid(__child, &__status, 0) != __child) {
274 		ATF_REQUIRE_EQ(EINTR, errno);
275 	}
276 
277 	if (!WIFSIGNALED(__status)) {
278 		switch (WEXITSTATUS(__status)) {
279 		case EX_SOFTWARE:
280 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
281 			break;
282 		case EX_OSERR:
283 			atf_tc_fail("setrlimit(2) failed");
284 			break;
285 		default:
286 			atf_tc_fail("child exited with status %d",
287 			    WEXITSTATUS(__status));
288 		}
289 	} else {
290 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
291 	}
292 #undef BUF
293 
294 }
295 
296 ATF_TC_WITHOUT_HEAD(FD_CLR_before_end);
297 ATF_TC_BODY(FD_CLR_before_end, tc)
298 {
299 #define BUF &__stack.__buf
300 	struct {
301 		uint8_t padding_l;
302 		fd_set __buf;
303 		uint8_t padding_r;
304 	} __stack;
305 	const size_t __bufsz __unused = sizeof(__stack.__buf);
306 	const size_t __len = FD_SETSIZE - 1;
307 	const size_t __idx __unused = __len - 1;
308 
309 	FD_CLR(__idx, &__stack.__buf);
310 #undef BUF
311 
312 }
313 
314 ATF_TC_WITHOUT_HEAD(FD_CLR_end);
315 ATF_TC_BODY(FD_CLR_end, tc)
316 {
317 #define BUF &__stack.__buf
318 	struct {
319 		uint8_t padding_l;
320 		fd_set __buf;
321 		uint8_t padding_r;
322 	} __stack;
323 	const size_t __bufsz __unused = sizeof(__stack.__buf);
324 	const size_t __len = FD_SETSIZE;
325 	const size_t __idx __unused = __len - 1;
326 
327 	FD_CLR(__idx, &__stack.__buf);
328 #undef BUF
329 
330 }
331 
332 ATF_TC_WITHOUT_HEAD(FD_CLR_after_end);
333 ATF_TC_BODY(FD_CLR_after_end, tc)
334 {
335 #define BUF &__stack.__buf
336 	struct {
337 		uint8_t padding_l;
338 		fd_set __buf;
339 		uint8_t padding_r;
340 	} __stack;
341 	const size_t __bufsz __unused = sizeof(__stack.__buf);
342 	const size_t __len = FD_SETSIZE + 1;
343 	const size_t __idx __unused = __len - 1;
344 	pid_t __child;
345 	int __status;
346 
347 	__child = fork();
348 	ATF_REQUIRE(__child >= 0);
349 	if (__child > 0)
350 		goto monitor;
351 
352 	/* Child */
353 	disable_coredumps();
354 	FD_CLR(__idx, &__stack.__buf);
355 	_exit(EX_SOFTWARE);	/* Should have aborted. */
356 
357 monitor:
358 	while (waitpid(__child, &__status, 0) != __child) {
359 		ATF_REQUIRE_EQ(EINTR, errno);
360 	}
361 
362 	if (!WIFSIGNALED(__status)) {
363 		switch (WEXITSTATUS(__status)) {
364 		case EX_SOFTWARE:
365 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
366 			break;
367 		case EX_OSERR:
368 			atf_tc_fail("setrlimit(2) failed");
369 			break;
370 		default:
371 			atf_tc_fail("child exited with status %d",
372 			    WEXITSTATUS(__status));
373 		}
374 	} else {
375 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
376 	}
377 #undef BUF
378 
379 }
380 
381 ATF_TC_WITHOUT_HEAD(FD_CLR_heap_before_end);
382 ATF_TC_BODY(FD_CLR_heap_before_end, tc)
383 {
384 #define BUF __stack.__buf
385 	struct {
386 		uint8_t padding_l;
387 		fd_set * __buf;
388 		uint8_t padding_r;
389 	} __stack;
390 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
391 	const size_t __len = FD_SETSIZE - 1;
392 	const size_t __idx __unused = __len - 1;
393 
394 	__stack.__buf = malloc(__bufsz);
395 
396 	FD_CLR(__idx, __stack.__buf);
397 #undef BUF
398 
399 }
400 
401 ATF_TC_WITHOUT_HEAD(FD_CLR_heap_end);
402 ATF_TC_BODY(FD_CLR_heap_end, tc)
403 {
404 #define BUF __stack.__buf
405 	struct {
406 		uint8_t padding_l;
407 		fd_set * __buf;
408 		uint8_t padding_r;
409 	} __stack;
410 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
411 	const size_t __len = FD_SETSIZE;
412 	const size_t __idx __unused = __len - 1;
413 
414 	__stack.__buf = malloc(__bufsz);
415 
416 	FD_CLR(__idx, __stack.__buf);
417 #undef BUF
418 
419 }
420 
421 ATF_TC_WITHOUT_HEAD(FD_CLR_heap_after_end);
422 ATF_TC_BODY(FD_CLR_heap_after_end, tc)
423 {
424 #define BUF __stack.__buf
425 	struct {
426 		uint8_t padding_l;
427 		fd_set * __buf;
428 		uint8_t padding_r;
429 	} __stack;
430 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
431 	const size_t __len = FD_SETSIZE + 1;
432 	const size_t __idx __unused = __len - 1;
433 	pid_t __child;
434 	int __status;
435 
436 	__child = fork();
437 	ATF_REQUIRE(__child >= 0);
438 	if (__child > 0)
439 		goto monitor;
440 
441 	/* Child */
442 	disable_coredumps();
443 	__stack.__buf = malloc(__bufsz);
444 
445 	FD_CLR(__idx, __stack.__buf);
446 	_exit(EX_SOFTWARE);	/* Should have aborted. */
447 
448 monitor:
449 	while (waitpid(__child, &__status, 0) != __child) {
450 		ATF_REQUIRE_EQ(EINTR, errno);
451 	}
452 
453 	if (!WIFSIGNALED(__status)) {
454 		switch (WEXITSTATUS(__status)) {
455 		case EX_SOFTWARE:
456 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
457 			break;
458 		case EX_OSERR:
459 			atf_tc_fail("setrlimit(2) failed");
460 			break;
461 		default:
462 			atf_tc_fail("child exited with status %d",
463 			    WEXITSTATUS(__status));
464 		}
465 	} else {
466 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
467 	}
468 #undef BUF
469 
470 }
471 
472 ATF_TC_WITHOUT_HEAD(FD_ISSET_before_end);
473 ATF_TC_BODY(FD_ISSET_before_end, tc)
474 {
475 #define BUF &__stack.__buf
476 	struct {
477 		uint8_t padding_l;
478 		fd_set __buf;
479 		uint8_t padding_r;
480 	} __stack;
481 	const size_t __bufsz __unused = sizeof(__stack.__buf);
482 	const size_t __len = FD_SETSIZE - 1;
483 	const size_t __idx __unused = __len - 1;
484 
485 	FD_ISSET(__idx, &__stack.__buf);
486 #undef BUF
487 
488 }
489 
490 ATF_TC_WITHOUT_HEAD(FD_ISSET_end);
491 ATF_TC_BODY(FD_ISSET_end, tc)
492 {
493 #define BUF &__stack.__buf
494 	struct {
495 		uint8_t padding_l;
496 		fd_set __buf;
497 		uint8_t padding_r;
498 	} __stack;
499 	const size_t __bufsz __unused = sizeof(__stack.__buf);
500 	const size_t __len = FD_SETSIZE;
501 	const size_t __idx __unused = __len - 1;
502 
503 	FD_ISSET(__idx, &__stack.__buf);
504 #undef BUF
505 
506 }
507 
508 ATF_TC_WITHOUT_HEAD(FD_ISSET_after_end);
509 ATF_TC_BODY(FD_ISSET_after_end, tc)
510 {
511 #define BUF &__stack.__buf
512 	struct {
513 		uint8_t padding_l;
514 		fd_set __buf;
515 		uint8_t padding_r;
516 	} __stack;
517 	const size_t __bufsz __unused = sizeof(__stack.__buf);
518 	const size_t __len = FD_SETSIZE + 1;
519 	const size_t __idx __unused = __len - 1;
520 	pid_t __child;
521 	int __status;
522 
523 	__child = fork();
524 	ATF_REQUIRE(__child >= 0);
525 	if (__child > 0)
526 		goto monitor;
527 
528 	/* Child */
529 	disable_coredumps();
530 	FD_ISSET(__idx, &__stack.__buf);
531 	_exit(EX_SOFTWARE);	/* Should have aborted. */
532 
533 monitor:
534 	while (waitpid(__child, &__status, 0) != __child) {
535 		ATF_REQUIRE_EQ(EINTR, errno);
536 	}
537 
538 	if (!WIFSIGNALED(__status)) {
539 		switch (WEXITSTATUS(__status)) {
540 		case EX_SOFTWARE:
541 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
542 			break;
543 		case EX_OSERR:
544 			atf_tc_fail("setrlimit(2) failed");
545 			break;
546 		default:
547 			atf_tc_fail("child exited with status %d",
548 			    WEXITSTATUS(__status));
549 		}
550 	} else {
551 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
552 	}
553 #undef BUF
554 
555 }
556 
557 ATF_TC_WITHOUT_HEAD(FD_ISSET_heap_before_end);
558 ATF_TC_BODY(FD_ISSET_heap_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) * (1);
567 	const size_t __len = FD_SETSIZE - 1;
568 	const size_t __idx __unused = __len - 1;
569 
570 	__stack.__buf = malloc(__bufsz);
571 
572 	FD_ISSET(__idx, __stack.__buf);
573 #undef BUF
574 
575 }
576 
577 ATF_TC_WITHOUT_HEAD(FD_ISSET_heap_end);
578 ATF_TC_BODY(FD_ISSET_heap_end, tc)
579 {
580 #define BUF __stack.__buf
581 	struct {
582 		uint8_t padding_l;
583 		fd_set * __buf;
584 		uint8_t padding_r;
585 	} __stack;
586 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
587 	const size_t __len = FD_SETSIZE;
588 	const size_t __idx __unused = __len - 1;
589 
590 	__stack.__buf = malloc(__bufsz);
591 
592 	FD_ISSET(__idx, __stack.__buf);
593 #undef BUF
594 
595 }
596 
597 ATF_TC_WITHOUT_HEAD(FD_ISSET_heap_after_end);
598 ATF_TC_BODY(FD_ISSET_heap_after_end, tc)
599 {
600 #define BUF __stack.__buf
601 	struct {
602 		uint8_t padding_l;
603 		fd_set * __buf;
604 		uint8_t padding_r;
605 	} __stack;
606 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
607 	const size_t __len = FD_SETSIZE + 1;
608 	const size_t __idx __unused = __len - 1;
609 	pid_t __child;
610 	int __status;
611 
612 	__child = fork();
613 	ATF_REQUIRE(__child >= 0);
614 	if (__child > 0)
615 		goto monitor;
616 
617 	/* Child */
618 	disable_coredumps();
619 	__stack.__buf = malloc(__bufsz);
620 
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_TP_ADD_TCS(tp)
649 {
650 	ATF_TP_ADD_TC(tp, FD_SET_before_end);
651 	ATF_TP_ADD_TC(tp, FD_SET_end);
652 	ATF_TP_ADD_TC(tp, FD_SET_after_end);
653 	ATF_TP_ADD_TC(tp, FD_SET_heap_before_end);
654 	ATF_TP_ADD_TC(tp, FD_SET_heap_end);
655 	ATF_TP_ADD_TC(tp, FD_SET_heap_after_end);
656 	ATF_TP_ADD_TC(tp, FD_CLR_before_end);
657 	ATF_TP_ADD_TC(tp, FD_CLR_end);
658 	ATF_TP_ADD_TC(tp, FD_CLR_after_end);
659 	ATF_TP_ADD_TC(tp, FD_CLR_heap_before_end);
660 	ATF_TP_ADD_TC(tp, FD_CLR_heap_end);
661 	ATF_TP_ADD_TC(tp, FD_CLR_heap_after_end);
662 	ATF_TP_ADD_TC(tp, FD_ISSET_before_end);
663 	ATF_TP_ADD_TC(tp, FD_ISSET_end);
664 	ATF_TP_ADD_TC(tp, FD_ISSET_after_end);
665 	ATF_TP_ADD_TC(tp, FD_ISSET_heap_before_end);
666 	ATF_TP_ADD_TC(tp, FD_ISSET_heap_end);
667 	ATF_TP_ADD_TC(tp, FD_ISSET_heap_after_end);
668 	return (atf_no_error());
669 }
670