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