1*b0334450SRicardo Branco /* @generated by `generate-fortify-tests.lua "signal"` */
2*b0334450SRicardo Branco
3*b0334450SRicardo Branco #define _FORTIFY_SOURCE 2
4*b0334450SRicardo Branco #define TMPFILE_SIZE (1024 * 32)
5*b0334450SRicardo Branco
6*b0334450SRicardo Branco #include <sys/param.h>
7*b0334450SRicardo Branco #include <sys/jail.h>
8*b0334450SRicardo Branco #include <sys/random.h>
9*b0334450SRicardo Branco #include <sys/resource.h>
10*b0334450SRicardo Branco #include <sys/select.h>
11*b0334450SRicardo Branco #include <sys/socket.h>
12*b0334450SRicardo Branco #include <sys/time.h>
13*b0334450SRicardo Branco #include <sys/uio.h>
14*b0334450SRicardo Branco #include <sys/wait.h>
15*b0334450SRicardo Branco #include <dirent.h>
16*b0334450SRicardo Branco #include <errno.h>
17*b0334450SRicardo Branco #include <fcntl.h>
18*b0334450SRicardo Branco #include <limits.h>
19*b0334450SRicardo Branco #include <poll.h>
20*b0334450SRicardo Branco #include <signal.h>
21*b0334450SRicardo Branco #include <stdio.h>
22*b0334450SRicardo Branco #include <stdlib.h>
23*b0334450SRicardo Branco #include <string.h>
24*b0334450SRicardo Branco #include <strings.h>
25*b0334450SRicardo Branco #include <sysexits.h>
26*b0334450SRicardo Branco #include <unistd.h>
27*b0334450SRicardo Branco #include <wchar.h>
28*b0334450SRicardo Branco #include <atf-c.h>
29*b0334450SRicardo Branco
30*b0334450SRicardo Branco static FILE * __unused
new_fp(size_t __len)31*b0334450SRicardo Branco new_fp(size_t __len)
32*b0334450SRicardo Branco {
33*b0334450SRicardo Branco static char fpbuf[LINE_MAX];
34*b0334450SRicardo Branco FILE *fp;
35*b0334450SRicardo Branco
36*b0334450SRicardo Branco ATF_REQUIRE(__len <= sizeof(fpbuf));
37*b0334450SRicardo Branco
38*b0334450SRicardo Branco memset(fpbuf, 'A', sizeof(fpbuf) - 1);
39*b0334450SRicardo Branco fpbuf[sizeof(fpbuf) - 1] = '\0';
40*b0334450SRicardo Branco
41*b0334450SRicardo Branco fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
42*b0334450SRicardo Branco ATF_REQUIRE(fp != NULL);
43*b0334450SRicardo Branco
44*b0334450SRicardo Branco return (fp);
45*b0334450SRicardo Branco }
46*b0334450SRicardo Branco
47*b0334450SRicardo Branco /*
48*b0334450SRicardo Branco * Create a new symlink to use for readlink(2) style tests, we'll just use a
49*b0334450SRicardo Branco * random target name to have something interesting to look at.
50*b0334450SRicardo Branco */
51*b0334450SRicardo Branco static const char * __unused
new_symlink(size_t __len)52*b0334450SRicardo Branco new_symlink(size_t __len)
53*b0334450SRicardo Branco {
54*b0334450SRicardo Branco static const char linkname[] = "link";
55*b0334450SRicardo Branco char target[MAXNAMLEN];
56*b0334450SRicardo Branco int error;
57*b0334450SRicardo Branco
58*b0334450SRicardo Branco ATF_REQUIRE(__len <= sizeof(target));
59*b0334450SRicardo Branco
60*b0334450SRicardo Branco arc4random_buf(target, sizeof(target));
61*b0334450SRicardo Branco
62*b0334450SRicardo Branco error = unlink(linkname);
63*b0334450SRicardo Branco ATF_REQUIRE(error == 0 || errno == ENOENT);
64*b0334450SRicardo Branco
65*b0334450SRicardo Branco error = symlink(target, linkname);
66*b0334450SRicardo Branco ATF_REQUIRE(error == 0);
67*b0334450SRicardo Branco
68*b0334450SRicardo Branco return (linkname);
69*b0334450SRicardo Branco }
70*b0334450SRicardo Branco
71*b0334450SRicardo Branco /*
72*b0334450SRicardo Branco * For our purposes, first descriptor will be the reader; we'll send both
73*b0334450SRicardo Branco * raw data and a control message over it so that the result can be used for
74*b0334450SRicardo Branco * any of our recv*() tests.
75*b0334450SRicardo Branco */
76*b0334450SRicardo Branco static void __unused
new_socket(int sock[2])77*b0334450SRicardo Branco new_socket(int sock[2])
78*b0334450SRicardo Branco {
79*b0334450SRicardo Branco unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
80*b0334450SRicardo Branco static char sockbuf[256];
81*b0334450SRicardo Branco ssize_t rv;
82*b0334450SRicardo Branco size_t total = 0;
83*b0334450SRicardo Branco struct msghdr hdr = { 0 };
84*b0334450SRicardo Branco struct cmsghdr *cmsg;
85*b0334450SRicardo Branco int error, fd;
86*b0334450SRicardo Branco
87*b0334450SRicardo Branco error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
88*b0334450SRicardo Branco ATF_REQUIRE(error == 0);
89*b0334450SRicardo Branco
90*b0334450SRicardo Branco while (total != sizeof(sockbuf)) {
91*b0334450SRicardo Branco rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
92*b0334450SRicardo Branco
93*b0334450SRicardo Branco ATF_REQUIRE_MSG(rv > 0,
94*b0334450SRicardo Branco "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
95*b0334450SRicardo Branco rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
96*b0334450SRicardo Branco ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
97*b0334450SRicardo Branco "%zd exceeds total %zu", rv, sizeof(sockbuf));
98*b0334450SRicardo Branco total += rv;
99*b0334450SRicardo Branco }
100*b0334450SRicardo Branco
101*b0334450SRicardo Branco hdr.msg_control = ctrl;
102*b0334450SRicardo Branco hdr.msg_controllen = sizeof(ctrl);
103*b0334450SRicardo Branco
104*b0334450SRicardo Branco cmsg = CMSG_FIRSTHDR(&hdr);
105*b0334450SRicardo Branco cmsg->cmsg_level = SOL_SOCKET;
106*b0334450SRicardo Branco cmsg->cmsg_type = SCM_RIGHTS;
107*b0334450SRicardo Branco cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
108*b0334450SRicardo Branco fd = STDIN_FILENO;
109*b0334450SRicardo Branco memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
110*b0334450SRicardo Branco
111*b0334450SRicardo Branco error = sendmsg(sock[1], &hdr, 0);
112*b0334450SRicardo Branco ATF_REQUIRE(error != -1);
113*b0334450SRicardo Branco }
114*b0334450SRicardo Branco
115*b0334450SRicardo Branco /*
116*b0334450SRicardo Branco * Constructs a tmpfile that we can use for testing read(2) and friends.
117*b0334450SRicardo Branco */
118*b0334450SRicardo Branco static int __unused
new_tmpfile(void)119*b0334450SRicardo Branco new_tmpfile(void)
120*b0334450SRicardo Branco {
121*b0334450SRicardo Branco char buf[1024];
122*b0334450SRicardo Branco ssize_t rv;
123*b0334450SRicardo Branco size_t written;
124*b0334450SRicardo Branco int fd;
125*b0334450SRicardo Branco
126*b0334450SRicardo Branco fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
127*b0334450SRicardo Branco ATF_REQUIRE(fd >= 0);
128*b0334450SRicardo Branco
129*b0334450SRicardo Branco written = 0;
130*b0334450SRicardo Branco while (written < TMPFILE_SIZE) {
131*b0334450SRicardo Branco rv = write(fd, buf, sizeof(buf));
132*b0334450SRicardo Branco ATF_REQUIRE(rv > 0);
133*b0334450SRicardo Branco
134*b0334450SRicardo Branco written += rv;
135*b0334450SRicardo Branco }
136*b0334450SRicardo Branco
137*b0334450SRicardo Branco ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
138*b0334450SRicardo Branco return (fd);
139*b0334450SRicardo Branco }
140*b0334450SRicardo Branco
141*b0334450SRicardo Branco static void
disable_coredumps(void)142*b0334450SRicardo Branco disable_coredumps(void)
143*b0334450SRicardo Branco {
144*b0334450SRicardo Branco struct rlimit rl = { 0 };
145*b0334450SRicardo Branco
146*b0334450SRicardo Branco if (setrlimit(RLIMIT_CORE, &rl) == -1)
147*b0334450SRicardo Branco _exit(EX_OSERR);
148*b0334450SRicardo Branco }
149*b0334450SRicardo Branco
150*b0334450SRicardo Branco /*
151*b0334450SRicardo Branco * Replaces stdin with a file that we can actually read from, for tests where
152*b0334450SRicardo Branco * we want a FILE * or fd that we can get data from.
153*b0334450SRicardo Branco */
154*b0334450SRicardo Branco static void __unused
replace_stdin(void)155*b0334450SRicardo Branco replace_stdin(void)
156*b0334450SRicardo Branco {
157*b0334450SRicardo Branco int fd;
158*b0334450SRicardo Branco
159*b0334450SRicardo Branco fd = new_tmpfile();
160*b0334450SRicardo Branco
161*b0334450SRicardo Branco (void)dup2(fd, STDIN_FILENO);
162*b0334450SRicardo Branco if (fd != STDIN_FILENO)
163*b0334450SRicardo Branco close(fd);
164*b0334450SRicardo Branco }
165*b0334450SRicardo Branco
166*b0334450SRicardo Branco ATF_TC(sig2str_before_end);
ATF_TC_HEAD(sig2str_before_end,tc)167*b0334450SRicardo Branco ATF_TC_HEAD(sig2str_before_end, tc)
168*b0334450SRicardo Branco {
169*b0334450SRicardo Branco }
ATF_TC_BODY(sig2str_before_end,tc)170*b0334450SRicardo Branco ATF_TC_BODY(sig2str_before_end, tc)
171*b0334450SRicardo Branco {
172*b0334450SRicardo Branco #define BUF &__stack.__buf
173*b0334450SRicardo Branco struct {
174*b0334450SRicardo Branco uint8_t padding_l;
175*b0334450SRicardo Branco unsigned char __buf[SIG2STR_MAX + 1];
176*b0334450SRicardo Branco uint8_t padding_r;
177*b0334450SRicardo Branco } __stack;
178*b0334450SRicardo Branco const size_t __bufsz __unused = sizeof(__stack.__buf);
179*b0334450SRicardo Branco const size_t __len = SIG2STR_MAX + 1;
180*b0334450SRicardo Branco const size_t __idx __unused = __len - 1;
181*b0334450SRicardo Branco
182*b0334450SRicardo Branco sig2str(1, __stack.__buf);
183*b0334450SRicardo Branco #undef BUF
184*b0334450SRicardo Branco
185*b0334450SRicardo Branco }
186*b0334450SRicardo Branco
187*b0334450SRicardo Branco ATF_TC(sig2str_end);
ATF_TC_HEAD(sig2str_end,tc)188*b0334450SRicardo Branco ATF_TC_HEAD(sig2str_end, tc)
189*b0334450SRicardo Branco {
190*b0334450SRicardo Branco }
ATF_TC_BODY(sig2str_end,tc)191*b0334450SRicardo Branco ATF_TC_BODY(sig2str_end, tc)
192*b0334450SRicardo Branco {
193*b0334450SRicardo Branco #define BUF &__stack.__buf
194*b0334450SRicardo Branco struct {
195*b0334450SRicardo Branco uint8_t padding_l;
196*b0334450SRicardo Branco unsigned char __buf[SIG2STR_MAX];
197*b0334450SRicardo Branco uint8_t padding_r;
198*b0334450SRicardo Branco } __stack;
199*b0334450SRicardo Branco const size_t __bufsz __unused = sizeof(__stack.__buf);
200*b0334450SRicardo Branco const size_t __len = SIG2STR_MAX;
201*b0334450SRicardo Branco const size_t __idx __unused = __len - 1;
202*b0334450SRicardo Branco
203*b0334450SRicardo Branco sig2str(1, __stack.__buf);
204*b0334450SRicardo Branco #undef BUF
205*b0334450SRicardo Branco
206*b0334450SRicardo Branco }
207*b0334450SRicardo Branco
208*b0334450SRicardo Branco ATF_TC(sig2str_heap_before_end);
ATF_TC_HEAD(sig2str_heap_before_end,tc)209*b0334450SRicardo Branco ATF_TC_HEAD(sig2str_heap_before_end, tc)
210*b0334450SRicardo Branco {
211*b0334450SRicardo Branco }
ATF_TC_BODY(sig2str_heap_before_end,tc)212*b0334450SRicardo Branco ATF_TC_BODY(sig2str_heap_before_end, tc)
213*b0334450SRicardo Branco {
214*b0334450SRicardo Branco #define BUF __stack.__buf
215*b0334450SRicardo Branco struct {
216*b0334450SRicardo Branco uint8_t padding_l;
217*b0334450SRicardo Branco unsigned char * __buf;
218*b0334450SRicardo Branco uint8_t padding_r;
219*b0334450SRicardo Branco } __stack;
220*b0334450SRicardo Branco const size_t __bufsz __unused = sizeof(*__stack.__buf) * (SIG2STR_MAX + 1);
221*b0334450SRicardo Branco const size_t __len = SIG2STR_MAX + 1;
222*b0334450SRicardo Branco const size_t __idx __unused = __len - 1;
223*b0334450SRicardo Branco
224*b0334450SRicardo Branco __stack.__buf = malloc(__bufsz);
225*b0334450SRicardo Branco
226*b0334450SRicardo Branco sig2str(1, __stack.__buf);
227*b0334450SRicardo Branco #undef BUF
228*b0334450SRicardo Branco
229*b0334450SRicardo Branco }
230*b0334450SRicardo Branco
231*b0334450SRicardo Branco ATF_TC(sig2str_heap_end);
ATF_TC_HEAD(sig2str_heap_end,tc)232*b0334450SRicardo Branco ATF_TC_HEAD(sig2str_heap_end, tc)
233*b0334450SRicardo Branco {
234*b0334450SRicardo Branco }
ATF_TC_BODY(sig2str_heap_end,tc)235*b0334450SRicardo Branco ATF_TC_BODY(sig2str_heap_end, tc)
236*b0334450SRicardo Branco {
237*b0334450SRicardo Branco #define BUF __stack.__buf
238*b0334450SRicardo Branco struct {
239*b0334450SRicardo Branco uint8_t padding_l;
240*b0334450SRicardo Branco unsigned char * __buf;
241*b0334450SRicardo Branco uint8_t padding_r;
242*b0334450SRicardo Branco } __stack;
243*b0334450SRicardo Branco const size_t __bufsz __unused = sizeof(*__stack.__buf) * (SIG2STR_MAX);
244*b0334450SRicardo Branco const size_t __len = SIG2STR_MAX;
245*b0334450SRicardo Branco const size_t __idx __unused = __len - 1;
246*b0334450SRicardo Branco
247*b0334450SRicardo Branco __stack.__buf = malloc(__bufsz);
248*b0334450SRicardo Branco
249*b0334450SRicardo Branco sig2str(1, __stack.__buf);
250*b0334450SRicardo Branco #undef BUF
251*b0334450SRicardo Branco
252*b0334450SRicardo Branco }
253*b0334450SRicardo Branco
254*b0334450SRicardo Branco ATF_TC(sig2str_heap_after_end);
ATF_TC_HEAD(sig2str_heap_after_end,tc)255*b0334450SRicardo Branco ATF_TC_HEAD(sig2str_heap_after_end, tc)
256*b0334450SRicardo Branco {
257*b0334450SRicardo Branco }
ATF_TC_BODY(sig2str_heap_after_end,tc)258*b0334450SRicardo Branco ATF_TC_BODY(sig2str_heap_after_end, tc)
259*b0334450SRicardo Branco {
260*b0334450SRicardo Branco #define BUF __stack.__buf
261*b0334450SRicardo Branco struct {
262*b0334450SRicardo Branco uint8_t padding_l;
263*b0334450SRicardo Branco unsigned char * __buf;
264*b0334450SRicardo Branco uint8_t padding_r;
265*b0334450SRicardo Branco } __stack;
266*b0334450SRicardo Branco const size_t __bufsz __unused = sizeof(*__stack.__buf) * (SIG2STR_MAX - 1);
267*b0334450SRicardo Branco const size_t __len = SIG2STR_MAX - 1;
268*b0334450SRicardo Branco const size_t __idx __unused = __len - 1;
269*b0334450SRicardo Branco pid_t __child;
270*b0334450SRicardo Branco int __status;
271*b0334450SRicardo Branco
272*b0334450SRicardo Branco __child = fork();
273*b0334450SRicardo Branco ATF_REQUIRE(__child >= 0);
274*b0334450SRicardo Branco if (__child > 0)
275*b0334450SRicardo Branco goto monitor;
276*b0334450SRicardo Branco
277*b0334450SRicardo Branco /* Child */
278*b0334450SRicardo Branco disable_coredumps();
279*b0334450SRicardo Branco __stack.__buf = malloc(__bufsz);
280*b0334450SRicardo Branco
281*b0334450SRicardo Branco sig2str(1, __stack.__buf);
282*b0334450SRicardo Branco _exit(EX_SOFTWARE); /* Should have aborted. */
283*b0334450SRicardo Branco
284*b0334450SRicardo Branco monitor:
285*b0334450SRicardo Branco while (waitpid(__child, &__status, 0) != __child) {
286*b0334450SRicardo Branco ATF_REQUIRE_EQ(EINTR, errno);
287*b0334450SRicardo Branco }
288*b0334450SRicardo Branco
289*b0334450SRicardo Branco if (!WIFSIGNALED(__status)) {
290*b0334450SRicardo Branco switch (WEXITSTATUS(__status)) {
291*b0334450SRicardo Branco case EX_SOFTWARE:
292*b0334450SRicardo Branco atf_tc_fail("FORTIFY_SOURCE failed to abort");
293*b0334450SRicardo Branco break;
294*b0334450SRicardo Branco case EX_OSERR:
295*b0334450SRicardo Branco atf_tc_fail("setrlimit(2) failed");
296*b0334450SRicardo Branco break;
297*b0334450SRicardo Branco default:
298*b0334450SRicardo Branco atf_tc_fail("child exited with status %d",
299*b0334450SRicardo Branco WEXITSTATUS(__status));
300*b0334450SRicardo Branco }
301*b0334450SRicardo Branco } else {
302*b0334450SRicardo Branco ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
303*b0334450SRicardo Branco }
304*b0334450SRicardo Branco #undef BUF
305*b0334450SRicardo Branco
306*b0334450SRicardo Branco }
307*b0334450SRicardo Branco
ATF_TP_ADD_TCS(tp)308*b0334450SRicardo Branco ATF_TP_ADD_TCS(tp)
309*b0334450SRicardo Branco {
310*b0334450SRicardo Branco ATF_TP_ADD_TC(tp, sig2str_before_end);
311*b0334450SRicardo Branco ATF_TP_ADD_TC(tp, sig2str_end);
312*b0334450SRicardo Branco ATF_TP_ADD_TC(tp, sig2str_heap_before_end);
313*b0334450SRicardo Branco ATF_TP_ADD_TC(tp, sig2str_heap_end);
314*b0334450SRicardo Branco ATF_TP_ADD_TC(tp, sig2str_heap_after_end);
315*b0334450SRicardo Branco return (atf_no_error());
316*b0334450SRicardo Branco }
317