xref: /freebsd/lib/libc/tests/secure/fortify_poll_test.c (revision 1ace24b30cad59c8ae509d0c690aa55b8df73136)
1 /* @generated by `generate-fortify-tests.lua "poll"` */
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(poll_before_end);
120 ATF_TC_BODY(poll_before_end, tc)
121 {
122 #define BUF &__stack.__buf
123 	struct {
124 		uint8_t padding_l;
125 		struct pollfd __buf[4];
126 		uint8_t padding_r;
127 	} __stack;
128 	const size_t __bufsz __unused = sizeof(__stack.__buf);
129 	const size_t __len = 4 - 1;
130 	const size_t __idx __unused = __len - 1;
131 
132 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
133 		__stack.__buf[i].fd = -1;
134 	}
135 
136 	poll(__stack.__buf, __len, 0);
137 #undef BUF
138 
139 }
140 
141 ATF_TC_WITHOUT_HEAD(poll_end);
142 ATF_TC_BODY(poll_end, tc)
143 {
144 #define BUF &__stack.__buf
145 	struct {
146 		uint8_t padding_l;
147 		struct pollfd __buf[4];
148 		uint8_t padding_r;
149 	} __stack;
150 	const size_t __bufsz __unused = sizeof(__stack.__buf);
151 	const size_t __len = 4;
152 	const size_t __idx __unused = __len - 1;
153 
154 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
155 		__stack.__buf[i].fd = -1;
156 	}
157 
158 	poll(__stack.__buf, __len, 0);
159 #undef BUF
160 
161 }
162 
163 ATF_TC_WITHOUT_HEAD(poll_after_end);
164 ATF_TC_BODY(poll_after_end, tc)
165 {
166 #define BUF &__stack.__buf
167 	struct {
168 		uint8_t padding_l;
169 		struct pollfd __buf[4];
170 		uint8_t padding_r;
171 	} __stack;
172 	const size_t __bufsz __unused = sizeof(__stack.__buf);
173 	const size_t __len = 4 + 1;
174 	const size_t __idx __unused = __len - 1;
175 	pid_t __child;
176 	int __status;
177 
178 	__child = fork();
179 	ATF_REQUIRE(__child >= 0);
180 	if (__child > 0)
181 		goto monitor;
182 
183 	/* Child */
184 	disable_coredumps();
185 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
186 		__stack.__buf[i].fd = -1;
187 	}
188 
189 	poll(__stack.__buf, __len, 0);
190 	_exit(EX_SOFTWARE);	/* Should have aborted. */
191 
192 monitor:
193 	while (waitpid(__child, &__status, 0) != __child) {
194 		ATF_REQUIRE_EQ(EINTR, errno);
195 	}
196 
197 	if (!WIFSIGNALED(__status)) {
198 		switch (WEXITSTATUS(__status)) {
199 		case EX_SOFTWARE:
200 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
201 			break;
202 		case EX_OSERR:
203 			atf_tc_fail("setrlimit(2) failed");
204 			break;
205 		default:
206 			atf_tc_fail("child exited with status %d",
207 			    WEXITSTATUS(__status));
208 		}
209 	} else {
210 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
211 	}
212 #undef BUF
213 
214 }
215 
216 ATF_TC_WITHOUT_HEAD(poll_heap_before_end);
217 ATF_TC_BODY(poll_heap_before_end, tc)
218 {
219 #define BUF __stack.__buf
220 	struct {
221 		uint8_t padding_l;
222 		struct pollfd * __buf;
223 		uint8_t padding_r;
224 	} __stack;
225 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
226 	const size_t __len = 4 - 1;
227 	const size_t __idx __unused = __len - 1;
228 
229 	__stack.__buf = malloc(__bufsz);
230 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
231 		__stack.__buf[i].fd = -1;
232 	}
233 
234 	poll(__stack.__buf, __len, 0);
235 #undef BUF
236 
237 }
238 
239 ATF_TC_WITHOUT_HEAD(poll_heap_end);
240 ATF_TC_BODY(poll_heap_end, tc)
241 {
242 #define BUF __stack.__buf
243 	struct {
244 		uint8_t padding_l;
245 		struct pollfd * __buf;
246 		uint8_t padding_r;
247 	} __stack;
248 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
249 	const size_t __len = 4;
250 	const size_t __idx __unused = __len - 1;
251 
252 	__stack.__buf = malloc(__bufsz);
253 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
254 		__stack.__buf[i].fd = -1;
255 	}
256 
257 	poll(__stack.__buf, __len, 0);
258 #undef BUF
259 
260 }
261 
262 ATF_TC_WITHOUT_HEAD(poll_heap_after_end);
263 ATF_TC_BODY(poll_heap_after_end, tc)
264 {
265 #define BUF __stack.__buf
266 	struct {
267 		uint8_t padding_l;
268 		struct pollfd * __buf;
269 		uint8_t padding_r;
270 	} __stack;
271 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
272 	const size_t __len = 4 + 1;
273 	const size_t __idx __unused = __len - 1;
274 	pid_t __child;
275 	int __status;
276 
277 	__child = fork();
278 	ATF_REQUIRE(__child >= 0);
279 	if (__child > 0)
280 		goto monitor;
281 
282 	/* Child */
283 	disable_coredumps();
284 	__stack.__buf = malloc(__bufsz);
285 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
286 		__stack.__buf[i].fd = -1;
287 	}
288 
289 	poll(__stack.__buf, __len, 0);
290 	_exit(EX_SOFTWARE);	/* Should have aborted. */
291 
292 monitor:
293 	while (waitpid(__child, &__status, 0) != __child) {
294 		ATF_REQUIRE_EQ(EINTR, errno);
295 	}
296 
297 	if (!WIFSIGNALED(__status)) {
298 		switch (WEXITSTATUS(__status)) {
299 		case EX_SOFTWARE:
300 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
301 			break;
302 		case EX_OSERR:
303 			atf_tc_fail("setrlimit(2) failed");
304 			break;
305 		default:
306 			atf_tc_fail("child exited with status %d",
307 			    WEXITSTATUS(__status));
308 		}
309 	} else {
310 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
311 	}
312 #undef BUF
313 
314 }
315 
316 ATF_TC_WITHOUT_HEAD(ppoll_before_end);
317 ATF_TC_BODY(ppoll_before_end, tc)
318 {
319 #define BUF &__stack.__buf
320 	struct {
321 		uint8_t padding_l;
322 		struct pollfd __buf[4];
323 		uint8_t padding_r;
324 	} __stack;
325 	const size_t __bufsz __unused = sizeof(__stack.__buf);
326 	const size_t __len = 4 - 1;
327 	const size_t __idx __unused = __len - 1;
328 	struct timespec tv = { 0 };
329 
330 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
331 		__stack.__buf[i].fd = -1;
332 	}
333 
334 	ppoll(__stack.__buf, __len, &tv, NULL);
335 #undef BUF
336 
337 }
338 
339 ATF_TC_WITHOUT_HEAD(ppoll_end);
340 ATF_TC_BODY(ppoll_end, tc)
341 {
342 #define BUF &__stack.__buf
343 	struct {
344 		uint8_t padding_l;
345 		struct pollfd __buf[4];
346 		uint8_t padding_r;
347 	} __stack;
348 	const size_t __bufsz __unused = sizeof(__stack.__buf);
349 	const size_t __len = 4;
350 	const size_t __idx __unused = __len - 1;
351 	struct timespec tv = { 0 };
352 
353 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
354 		__stack.__buf[i].fd = -1;
355 	}
356 
357 	ppoll(__stack.__buf, __len, &tv, NULL);
358 #undef BUF
359 
360 }
361 
362 ATF_TC_WITHOUT_HEAD(ppoll_after_end);
363 ATF_TC_BODY(ppoll_after_end, tc)
364 {
365 #define BUF &__stack.__buf
366 	struct {
367 		uint8_t padding_l;
368 		struct pollfd __buf[4];
369 		uint8_t padding_r;
370 	} __stack;
371 	const size_t __bufsz __unused = sizeof(__stack.__buf);
372 	const size_t __len = 4 + 1;
373 	const size_t __idx __unused = __len - 1;
374 	pid_t __child;
375 	int __status;
376 	struct timespec tv = { 0 };
377 
378 	__child = fork();
379 	ATF_REQUIRE(__child >= 0);
380 	if (__child > 0)
381 		goto monitor;
382 
383 	/* Child */
384 	disable_coredumps();
385 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
386 		__stack.__buf[i].fd = -1;
387 	}
388 
389 	ppoll(__stack.__buf, __len, &tv, NULL);
390 	_exit(EX_SOFTWARE);	/* Should have aborted. */
391 
392 monitor:
393 	while (waitpid(__child, &__status, 0) != __child) {
394 		ATF_REQUIRE_EQ(EINTR, errno);
395 	}
396 
397 	if (!WIFSIGNALED(__status)) {
398 		switch (WEXITSTATUS(__status)) {
399 		case EX_SOFTWARE:
400 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
401 			break;
402 		case EX_OSERR:
403 			atf_tc_fail("setrlimit(2) failed");
404 			break;
405 		default:
406 			atf_tc_fail("child exited with status %d",
407 			    WEXITSTATUS(__status));
408 		}
409 	} else {
410 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
411 	}
412 #undef BUF
413 
414 }
415 
416 ATF_TC_WITHOUT_HEAD(ppoll_heap_before_end);
417 ATF_TC_BODY(ppoll_heap_before_end, tc)
418 {
419 #define BUF __stack.__buf
420 	struct {
421 		uint8_t padding_l;
422 		struct pollfd * __buf;
423 		uint8_t padding_r;
424 	} __stack;
425 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
426 	const size_t __len = 4 - 1;
427 	const size_t __idx __unused = __len - 1;
428 	struct timespec tv = { 0 };
429 
430 	__stack.__buf = malloc(__bufsz);
431 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
432 		__stack.__buf[i].fd = -1;
433 	}
434 
435 	ppoll(__stack.__buf, __len, &tv, NULL);
436 #undef BUF
437 
438 }
439 
440 ATF_TC_WITHOUT_HEAD(ppoll_heap_end);
441 ATF_TC_BODY(ppoll_heap_end, tc)
442 {
443 #define BUF __stack.__buf
444 	struct {
445 		uint8_t padding_l;
446 		struct pollfd * __buf;
447 		uint8_t padding_r;
448 	} __stack;
449 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
450 	const size_t __len = 4;
451 	const size_t __idx __unused = __len - 1;
452 	struct timespec tv = { 0 };
453 
454 	__stack.__buf = malloc(__bufsz);
455 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
456 		__stack.__buf[i].fd = -1;
457 	}
458 
459 	ppoll(__stack.__buf, __len, &tv, NULL);
460 #undef BUF
461 
462 }
463 
464 ATF_TC_WITHOUT_HEAD(ppoll_heap_after_end);
465 ATF_TC_BODY(ppoll_heap_after_end, tc)
466 {
467 #define BUF __stack.__buf
468 	struct {
469 		uint8_t padding_l;
470 		struct pollfd * __buf;
471 		uint8_t padding_r;
472 	} __stack;
473 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
474 	const size_t __len = 4 + 1;
475 	const size_t __idx __unused = __len - 1;
476 	pid_t __child;
477 	int __status;
478 	struct timespec tv = { 0 };
479 
480 	__child = fork();
481 	ATF_REQUIRE(__child >= 0);
482 	if (__child > 0)
483 		goto monitor;
484 
485 	/* Child */
486 	disable_coredumps();
487 	__stack.__buf = malloc(__bufsz);
488 	for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) {
489 		__stack.__buf[i].fd = -1;
490 	}
491 
492 	ppoll(__stack.__buf, __len, &tv, NULL);
493 	_exit(EX_SOFTWARE);	/* Should have aborted. */
494 
495 monitor:
496 	while (waitpid(__child, &__status, 0) != __child) {
497 		ATF_REQUIRE_EQ(EINTR, errno);
498 	}
499 
500 	if (!WIFSIGNALED(__status)) {
501 		switch (WEXITSTATUS(__status)) {
502 		case EX_SOFTWARE:
503 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
504 			break;
505 		case EX_OSERR:
506 			atf_tc_fail("setrlimit(2) failed");
507 			break;
508 		default:
509 			atf_tc_fail("child exited with status %d",
510 			    WEXITSTATUS(__status));
511 		}
512 	} else {
513 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
514 	}
515 #undef BUF
516 
517 }
518 
519 ATF_TP_ADD_TCS(tp)
520 {
521 	ATF_TP_ADD_TC(tp, poll_before_end);
522 	ATF_TP_ADD_TC(tp, poll_end);
523 	ATF_TP_ADD_TC(tp, poll_after_end);
524 	ATF_TP_ADD_TC(tp, poll_heap_before_end);
525 	ATF_TP_ADD_TC(tp, poll_heap_end);
526 	ATF_TP_ADD_TC(tp, poll_heap_after_end);
527 	ATF_TP_ADD_TC(tp, ppoll_before_end);
528 	ATF_TP_ADD_TC(tp, ppoll_end);
529 	ATF_TP_ADD_TC(tp, ppoll_after_end);
530 	ATF_TP_ADD_TC(tp, ppoll_heap_before_end);
531 	ATF_TP_ADD_TC(tp, ppoll_heap_end);
532 	ATF_TP_ADD_TC(tp, ppoll_heap_after_end);
533 	return (atf_no_error());
534 }
535