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