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