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