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