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
new_fp(size_t __len)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
new_symlink(size_t __len)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
new_socket(int sock[2])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
new_tmpfile(void)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
disable_coredumps(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
replace_stdin(void)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);
ATF_TC_BODY(poll_before_end,tc)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);
ATF_TC_BODY(poll_end,tc)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);
ATF_TC_BODY(poll_after_end,tc)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);
ATF_TC_BODY(poll_heap_before_end,tc)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);
ATF_TC_BODY(poll_heap_end,tc)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);
ATF_TC_BODY(poll_heap_after_end,tc)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);
ATF_TC_BODY(ppoll_before_end,tc)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);
ATF_TC_BODY(ppoll_end,tc)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);
ATF_TC_BODY(ppoll_after_end,tc)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);
ATF_TC_BODY(ppoll_heap_before_end,tc)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);
ATF_TC_BODY(ppoll_heap_end,tc)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);
ATF_TC_BODY(ppoll_heap_after_end,tc)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
ATF_TP_ADD_TCS(tp)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