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