1 /* @generated by `generate-fortify-tests.lua "stdlib"` */
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(arc4random_buf_before_end);
ATF_TC_HEAD(arc4random_buf_before_end,tc)167 ATF_TC_HEAD(arc4random_buf_before_end, tc)
168 {
169 }
ATF_TC_BODY(arc4random_buf_before_end,tc)170 ATF_TC_BODY(arc4random_buf_before_end, tc)
171 {
172 #define BUF &__stack.__buf
173 struct {
174 uint8_t padding_l;
175 unsigned char __buf[42];
176 uint8_t padding_r;
177 } __stack;
178 const size_t __bufsz __unused = sizeof(__stack.__buf);
179 const size_t __len = 42 - 1;
180 const size_t __idx __unused = __len - 1;
181
182 arc4random_buf(__stack.__buf, __len);
183 #undef BUF
184
185 }
186
187 ATF_TC(arc4random_buf_end);
ATF_TC_HEAD(arc4random_buf_end,tc)188 ATF_TC_HEAD(arc4random_buf_end, tc)
189 {
190 }
ATF_TC_BODY(arc4random_buf_end,tc)191 ATF_TC_BODY(arc4random_buf_end, tc)
192 {
193 #define BUF &__stack.__buf
194 struct {
195 uint8_t padding_l;
196 unsigned char __buf[42];
197 uint8_t padding_r;
198 } __stack;
199 const size_t __bufsz __unused = sizeof(__stack.__buf);
200 const size_t __len = 42;
201 const size_t __idx __unused = __len - 1;
202
203 arc4random_buf(__stack.__buf, __len);
204 #undef BUF
205
206 }
207
208 ATF_TC(arc4random_buf_heap_before_end);
ATF_TC_HEAD(arc4random_buf_heap_before_end,tc)209 ATF_TC_HEAD(arc4random_buf_heap_before_end, tc)
210 {
211 }
ATF_TC_BODY(arc4random_buf_heap_before_end,tc)212 ATF_TC_BODY(arc4random_buf_heap_before_end, tc)
213 {
214 #define BUF __stack.__buf
215 struct {
216 uint8_t padding_l;
217 unsigned char * __buf;
218 uint8_t padding_r;
219 } __stack;
220 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
221 const size_t __len = 42 - 1;
222 const size_t __idx __unused = __len - 1;
223
224 __stack.__buf = malloc(__bufsz);
225
226 arc4random_buf(__stack.__buf, __len);
227 #undef BUF
228
229 }
230
231 ATF_TC(arc4random_buf_heap_end);
ATF_TC_HEAD(arc4random_buf_heap_end,tc)232 ATF_TC_HEAD(arc4random_buf_heap_end, tc)
233 {
234 }
ATF_TC_BODY(arc4random_buf_heap_end,tc)235 ATF_TC_BODY(arc4random_buf_heap_end, tc)
236 {
237 #define BUF __stack.__buf
238 struct {
239 uint8_t padding_l;
240 unsigned char * __buf;
241 uint8_t padding_r;
242 } __stack;
243 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
244 const size_t __len = 42;
245 const size_t __idx __unused = __len - 1;
246
247 __stack.__buf = malloc(__bufsz);
248
249 arc4random_buf(__stack.__buf, __len);
250 #undef BUF
251
252 }
253
254 ATF_TC(arc4random_buf_heap_after_end);
ATF_TC_HEAD(arc4random_buf_heap_after_end,tc)255 ATF_TC_HEAD(arc4random_buf_heap_after_end, tc)
256 {
257 }
ATF_TC_BODY(arc4random_buf_heap_after_end,tc)258 ATF_TC_BODY(arc4random_buf_heap_after_end, tc)
259 {
260 #define BUF __stack.__buf
261 struct {
262 uint8_t padding_l;
263 unsigned char * __buf;
264 uint8_t padding_r;
265 } __stack;
266 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
267 const size_t __len = 42 + 1;
268 const size_t __idx __unused = __len - 1;
269 pid_t __child;
270 int __status;
271
272 __child = fork();
273 ATF_REQUIRE(__child >= 0);
274 if (__child > 0)
275 goto monitor;
276
277 /* Child */
278 disable_coredumps();
279 __stack.__buf = malloc(__bufsz);
280
281 arc4random_buf(__stack.__buf, __len);
282 _exit(EX_SOFTWARE); /* Should have aborted. */
283
284 monitor:
285 while (waitpid(__child, &__status, 0) != __child) {
286 ATF_REQUIRE_EQ(EINTR, errno);
287 }
288
289 if (!WIFSIGNALED(__status)) {
290 switch (WEXITSTATUS(__status)) {
291 case EX_SOFTWARE:
292 atf_tc_fail("FORTIFY_SOURCE failed to abort");
293 break;
294 case EX_OSERR:
295 atf_tc_fail("setrlimit(2) failed");
296 break;
297 default:
298 atf_tc_fail("child exited with status %d",
299 WEXITSTATUS(__status));
300 }
301 } else {
302 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
303 }
304 #undef BUF
305
306 }
307
308 ATF_TC(getenv_r_before_end);
ATF_TC_HEAD(getenv_r_before_end,tc)309 ATF_TC_HEAD(getenv_r_before_end, tc)
310 {
311 }
ATF_TC_BODY(getenv_r_before_end,tc)312 ATF_TC_BODY(getenv_r_before_end, tc)
313 {
314 #define BUF &__stack.__buf
315 struct {
316 uint8_t padding_l;
317 unsigned char __buf[42];
318 uint8_t padding_r;
319 } __stack;
320 const size_t __bufsz __unused = sizeof(__stack.__buf);
321 const size_t __len = 42 - 1;
322 const size_t __idx __unused = __len - 1;
323
324 getenv_r("PATH", __stack.__buf, __len);
325 #undef BUF
326
327 }
328
329 ATF_TC(getenv_r_end);
ATF_TC_HEAD(getenv_r_end,tc)330 ATF_TC_HEAD(getenv_r_end, tc)
331 {
332 }
ATF_TC_BODY(getenv_r_end,tc)333 ATF_TC_BODY(getenv_r_end, tc)
334 {
335 #define BUF &__stack.__buf
336 struct {
337 uint8_t padding_l;
338 unsigned char __buf[42];
339 uint8_t padding_r;
340 } __stack;
341 const size_t __bufsz __unused = sizeof(__stack.__buf);
342 const size_t __len = 42;
343 const size_t __idx __unused = __len - 1;
344
345 getenv_r("PATH", __stack.__buf, __len);
346 #undef BUF
347
348 }
349
350 ATF_TC(getenv_r_heap_before_end);
ATF_TC_HEAD(getenv_r_heap_before_end,tc)351 ATF_TC_HEAD(getenv_r_heap_before_end, tc)
352 {
353 }
ATF_TC_BODY(getenv_r_heap_before_end,tc)354 ATF_TC_BODY(getenv_r_heap_before_end, tc)
355 {
356 #define BUF __stack.__buf
357 struct {
358 uint8_t padding_l;
359 unsigned char * __buf;
360 uint8_t padding_r;
361 } __stack;
362 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
363 const size_t __len = 42 - 1;
364 const size_t __idx __unused = __len - 1;
365
366 __stack.__buf = malloc(__bufsz);
367
368 getenv_r("PATH", __stack.__buf, __len);
369 #undef BUF
370
371 }
372
373 ATF_TC(getenv_r_heap_end);
ATF_TC_HEAD(getenv_r_heap_end,tc)374 ATF_TC_HEAD(getenv_r_heap_end, tc)
375 {
376 }
ATF_TC_BODY(getenv_r_heap_end,tc)377 ATF_TC_BODY(getenv_r_heap_end, tc)
378 {
379 #define BUF __stack.__buf
380 struct {
381 uint8_t padding_l;
382 unsigned char * __buf;
383 uint8_t padding_r;
384 } __stack;
385 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
386 const size_t __len = 42;
387 const size_t __idx __unused = __len - 1;
388
389 __stack.__buf = malloc(__bufsz);
390
391 getenv_r("PATH", __stack.__buf, __len);
392 #undef BUF
393
394 }
395
396 ATF_TC(getenv_r_heap_after_end);
ATF_TC_HEAD(getenv_r_heap_after_end,tc)397 ATF_TC_HEAD(getenv_r_heap_after_end, tc)
398 {
399 }
ATF_TC_BODY(getenv_r_heap_after_end,tc)400 ATF_TC_BODY(getenv_r_heap_after_end, tc)
401 {
402 #define BUF __stack.__buf
403 struct {
404 uint8_t padding_l;
405 unsigned char * __buf;
406 uint8_t padding_r;
407 } __stack;
408 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
409 const size_t __len = 42 + 1;
410 const size_t __idx __unused = __len - 1;
411 pid_t __child;
412 int __status;
413
414 __child = fork();
415 ATF_REQUIRE(__child >= 0);
416 if (__child > 0)
417 goto monitor;
418
419 /* Child */
420 disable_coredumps();
421 __stack.__buf = malloc(__bufsz);
422
423 getenv_r("PATH", __stack.__buf, __len);
424 _exit(EX_SOFTWARE); /* Should have aborted. */
425
426 monitor:
427 while (waitpid(__child, &__status, 0) != __child) {
428 ATF_REQUIRE_EQ(EINTR, errno);
429 }
430
431 if (!WIFSIGNALED(__status)) {
432 switch (WEXITSTATUS(__status)) {
433 case EX_SOFTWARE:
434 atf_tc_fail("FORTIFY_SOURCE failed to abort");
435 break;
436 case EX_OSERR:
437 atf_tc_fail("setrlimit(2) failed");
438 break;
439 default:
440 atf_tc_fail("child exited with status %d",
441 WEXITSTATUS(__status));
442 }
443 } else {
444 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
445 }
446 #undef BUF
447
448 }
449
450 ATF_TC(realpath_before_end);
ATF_TC_HEAD(realpath_before_end,tc)451 ATF_TC_HEAD(realpath_before_end, tc)
452 {
453 }
ATF_TC_BODY(realpath_before_end,tc)454 ATF_TC_BODY(realpath_before_end, tc)
455 {
456 #define BUF &__stack.__buf
457 struct {
458 uint8_t padding_l;
459 unsigned char __buf[PATH_MAX + 1];
460 uint8_t padding_r;
461 } __stack;
462 const size_t __bufsz __unused = sizeof(__stack.__buf);
463 const size_t __len = PATH_MAX + 1;
464 const size_t __idx __unused = __len - 1;
465
466 realpath(".", __stack.__buf);
467 #undef BUF
468
469 }
470
471 ATF_TC(realpath_end);
ATF_TC_HEAD(realpath_end,tc)472 ATF_TC_HEAD(realpath_end, tc)
473 {
474 }
ATF_TC_BODY(realpath_end,tc)475 ATF_TC_BODY(realpath_end, tc)
476 {
477 #define BUF &__stack.__buf
478 struct {
479 uint8_t padding_l;
480 unsigned char __buf[PATH_MAX];
481 uint8_t padding_r;
482 } __stack;
483 const size_t __bufsz __unused = sizeof(__stack.__buf);
484 const size_t __len = PATH_MAX;
485 const size_t __idx __unused = __len - 1;
486
487 realpath(".", __stack.__buf);
488 #undef BUF
489
490 }
491
492 ATF_TC(realpath_heap_before_end);
ATF_TC_HEAD(realpath_heap_before_end,tc)493 ATF_TC_HEAD(realpath_heap_before_end, tc)
494 {
495 }
ATF_TC_BODY(realpath_heap_before_end,tc)496 ATF_TC_BODY(realpath_heap_before_end, tc)
497 {
498 #define BUF __stack.__buf
499 struct {
500 uint8_t padding_l;
501 unsigned char * __buf;
502 uint8_t padding_r;
503 } __stack;
504 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX + 1);
505 const size_t __len = PATH_MAX + 1;
506 const size_t __idx __unused = __len - 1;
507
508 __stack.__buf = malloc(__bufsz);
509
510 realpath(".", __stack.__buf);
511 #undef BUF
512
513 }
514
515 ATF_TC(realpath_heap_end);
ATF_TC_HEAD(realpath_heap_end,tc)516 ATF_TC_HEAD(realpath_heap_end, tc)
517 {
518 }
ATF_TC_BODY(realpath_heap_end,tc)519 ATF_TC_BODY(realpath_heap_end, tc)
520 {
521 #define BUF __stack.__buf
522 struct {
523 uint8_t padding_l;
524 unsigned char * __buf;
525 uint8_t padding_r;
526 } __stack;
527 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX);
528 const size_t __len = PATH_MAX;
529 const size_t __idx __unused = __len - 1;
530
531 __stack.__buf = malloc(__bufsz);
532
533 realpath(".", __stack.__buf);
534 #undef BUF
535
536 }
537
538 ATF_TC(realpath_heap_after_end);
ATF_TC_HEAD(realpath_heap_after_end,tc)539 ATF_TC_HEAD(realpath_heap_after_end, tc)
540 {
541 }
ATF_TC_BODY(realpath_heap_after_end,tc)542 ATF_TC_BODY(realpath_heap_after_end, tc)
543 {
544 #define BUF __stack.__buf
545 struct {
546 uint8_t padding_l;
547 unsigned char * __buf;
548 uint8_t padding_r;
549 } __stack;
550 const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX - 1);
551 const size_t __len = PATH_MAX - 1;
552 const size_t __idx __unused = __len - 1;
553 pid_t __child;
554 int __status;
555
556 __child = fork();
557 ATF_REQUIRE(__child >= 0);
558 if (__child > 0)
559 goto monitor;
560
561 /* Child */
562 disable_coredumps();
563 __stack.__buf = malloc(__bufsz);
564
565 realpath(".", __stack.__buf);
566 _exit(EX_SOFTWARE); /* Should have aborted. */
567
568 monitor:
569 while (waitpid(__child, &__status, 0) != __child) {
570 ATF_REQUIRE_EQ(EINTR, errno);
571 }
572
573 if (!WIFSIGNALED(__status)) {
574 switch (WEXITSTATUS(__status)) {
575 case EX_SOFTWARE:
576 atf_tc_fail("FORTIFY_SOURCE failed to abort");
577 break;
578 case EX_OSERR:
579 atf_tc_fail("setrlimit(2) failed");
580 break;
581 default:
582 atf_tc_fail("child exited with status %d",
583 WEXITSTATUS(__status));
584 }
585 } else {
586 ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
587 }
588 #undef BUF
589
590 }
591
ATF_TP_ADD_TCS(tp)592 ATF_TP_ADD_TCS(tp)
593 {
594 ATF_TP_ADD_TC(tp, arc4random_buf_before_end);
595 ATF_TP_ADD_TC(tp, arc4random_buf_end);
596 ATF_TP_ADD_TC(tp, arc4random_buf_heap_before_end);
597 ATF_TP_ADD_TC(tp, arc4random_buf_heap_end);
598 ATF_TP_ADD_TC(tp, arc4random_buf_heap_after_end);
599 ATF_TP_ADD_TC(tp, getenv_r_before_end);
600 ATF_TP_ADD_TC(tp, getenv_r_end);
601 ATF_TP_ADD_TC(tp, getenv_r_heap_before_end);
602 ATF_TP_ADD_TC(tp, getenv_r_heap_end);
603 ATF_TP_ADD_TC(tp, getenv_r_heap_after_end);
604 ATF_TP_ADD_TC(tp, realpath_before_end);
605 ATF_TP_ADD_TC(tp, realpath_end);
606 ATF_TP_ADD_TC(tp, realpath_heap_before_end);
607 ATF_TP_ADD_TC(tp, realpath_heap_end);
608 ATF_TP_ADD_TC(tp, realpath_heap_after_end);
609 return (atf_no_error());
610 }
611