1062d9380SKyle Evans /* @generated by `generate-fortify-tests.lua "random"` */
2062d9380SKyle Evans
3062d9380SKyle Evans #define _FORTIFY_SOURCE 2
4062d9380SKyle Evans #define TMPFILE_SIZE (1024 * 32)
5062d9380SKyle Evans
6062d9380SKyle Evans #include <sys/param.h>
7*22178cb2SKyle Evans #include <sys/jail.h>
8062d9380SKyle Evans #include <sys/random.h>
9062d9380SKyle Evans #include <sys/resource.h>
102aba0eeaSKyle Evans #include <sys/select.h>
111f155d48SKyle Evans #include <sys/socket.h>
12062d9380SKyle Evans #include <sys/time.h>
131ace24b3SKyle Evans #include <sys/uio.h>
14062d9380SKyle Evans #include <sys/wait.h>
15062d9380SKyle Evans #include <dirent.h>
16062d9380SKyle Evans #include <errno.h>
17062d9380SKyle Evans #include <fcntl.h>
18062d9380SKyle Evans #include <limits.h>
19062d9380SKyle Evans #include <poll.h>
20062d9380SKyle Evans #include <signal.h>
21062d9380SKyle Evans #include <stdio.h>
22062d9380SKyle Evans #include <stdlib.h>
23062d9380SKyle Evans #include <string.h>
24062d9380SKyle Evans #include <strings.h>
25062d9380SKyle Evans #include <sysexits.h>
26062d9380SKyle Evans #include <unistd.h>
27062d9380SKyle Evans #include <wchar.h>
28062d9380SKyle Evans #include <atf-c.h>
29062d9380SKyle Evans
30062d9380SKyle Evans static FILE * __unused
new_fp(size_t __len)31062d9380SKyle Evans new_fp(size_t __len)
32062d9380SKyle Evans {
33062d9380SKyle Evans static char fpbuf[LINE_MAX];
34062d9380SKyle Evans FILE *fp;
35062d9380SKyle Evans
36062d9380SKyle Evans ATF_REQUIRE(__len <= sizeof(fpbuf));
37062d9380SKyle Evans
38062d9380SKyle Evans memset(fpbuf, 'A', sizeof(fpbuf) - 1);
39062d9380SKyle Evans fpbuf[sizeof(fpbuf) - 1] = '\0';
40062d9380SKyle Evans
41062d9380SKyle Evans fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
42062d9380SKyle Evans ATF_REQUIRE(fp != NULL);
43062d9380SKyle Evans
44062d9380SKyle Evans return (fp);
45062d9380SKyle Evans }
46062d9380SKyle Evans
47062d9380SKyle Evans /*
48062d9380SKyle Evans * Create a new symlink to use for readlink(2) style tests, we'll just use a
49062d9380SKyle Evans * random target name to have something interesting to look at.
50062d9380SKyle Evans */
51062d9380SKyle Evans static const char * __unused
new_symlink(size_t __len)52062d9380SKyle Evans new_symlink(size_t __len)
53062d9380SKyle Evans {
54062d9380SKyle Evans static const char linkname[] = "link";
55062d9380SKyle Evans char target[MAXNAMLEN];
56062d9380SKyle Evans int error;
57062d9380SKyle Evans
58062d9380SKyle Evans ATF_REQUIRE(__len <= sizeof(target));
59062d9380SKyle Evans
60062d9380SKyle Evans arc4random_buf(target, sizeof(target));
61062d9380SKyle Evans
62062d9380SKyle Evans error = unlink(linkname);
63062d9380SKyle Evans ATF_REQUIRE(error == 0 || errno == ENOENT);
64062d9380SKyle Evans
65062d9380SKyle Evans error = symlink(target, linkname);
66062d9380SKyle Evans ATF_REQUIRE(error == 0);
67062d9380SKyle Evans
68062d9380SKyle Evans return (linkname);
69062d9380SKyle Evans }
70062d9380SKyle Evans
71062d9380SKyle Evans /*
721f155d48SKyle Evans * For our purposes, first descriptor will be the reader; we'll send both
731f155d48SKyle Evans * raw data and a control message over it so that the result can be used for
741f155d48SKyle Evans * any of our recv*() tests.
751f155d48SKyle Evans */
761f155d48SKyle Evans static void __unused
new_socket(int sock[2])771f155d48SKyle Evans new_socket(int sock[2])
781f155d48SKyle Evans {
791f155d48SKyle Evans unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
801f155d48SKyle Evans static char sockbuf[256];
811f155d48SKyle Evans ssize_t rv;
821f155d48SKyle Evans size_t total = 0;
831f155d48SKyle Evans struct msghdr hdr = { 0 };
841f155d48SKyle Evans struct cmsghdr *cmsg;
851f155d48SKyle Evans int error, fd;
861f155d48SKyle Evans
871f155d48SKyle Evans error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
881f155d48SKyle Evans ATF_REQUIRE(error == 0);
891f155d48SKyle Evans
901f155d48SKyle Evans while (total != sizeof(sockbuf)) {
911f155d48SKyle Evans rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
921f155d48SKyle Evans
931f155d48SKyle Evans ATF_REQUIRE_MSG(rv > 0,
941f155d48SKyle Evans "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
951f155d48SKyle Evans rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
961f155d48SKyle Evans ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
971f155d48SKyle Evans "%zd exceeds total %zu", rv, sizeof(sockbuf));
981f155d48SKyle Evans total += rv;
991f155d48SKyle Evans }
1001f155d48SKyle Evans
1011f155d48SKyle Evans hdr.msg_control = ctrl;
1021f155d48SKyle Evans hdr.msg_controllen = sizeof(ctrl);
1031f155d48SKyle Evans
1041f155d48SKyle Evans cmsg = CMSG_FIRSTHDR(&hdr);
1051f155d48SKyle Evans cmsg->cmsg_level = SOL_SOCKET;
1061f155d48SKyle Evans cmsg->cmsg_type = SCM_RIGHTS;
1071f155d48SKyle Evans cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
1081f155d48SKyle Evans fd = STDIN_FILENO;
1091f155d48SKyle Evans memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
1101f155d48SKyle Evans
1111f155d48SKyle Evans error = sendmsg(sock[1], &hdr, 0);
1121f155d48SKyle Evans ATF_REQUIRE(error != -1);
1131f155d48SKyle Evans }
1141f155d48SKyle Evans
1151f155d48SKyle Evans /*
116062d9380SKyle Evans * Constructs a tmpfile that we can use for testing read(2) and friends.
117062d9380SKyle Evans */
118062d9380SKyle Evans static int __unused
new_tmpfile(void)119062d9380SKyle Evans new_tmpfile(void)
120062d9380SKyle Evans {
121062d9380SKyle Evans char buf[1024];
122062d9380SKyle Evans ssize_t rv;
123062d9380SKyle Evans size_t written;
124062d9380SKyle Evans int fd;
125062d9380SKyle Evans
126062d9380SKyle Evans fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
127062d9380SKyle Evans ATF_REQUIRE(fd >= 0);
128062d9380SKyle Evans
129062d9380SKyle Evans written = 0;
130062d9380SKyle Evans while (written < TMPFILE_SIZE) {
131062d9380SKyle Evans rv = write(fd, buf, sizeof(buf));
132062d9380SKyle Evans ATF_REQUIRE(rv > 0);
133062d9380SKyle Evans
134062d9380SKyle Evans written += rv;
135062d9380SKyle Evans }
136062d9380SKyle Evans
137062d9380SKyle Evans ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
138062d9380SKyle Evans return (fd);
139062d9380SKyle Evans }
140062d9380SKyle Evans
141062d9380SKyle Evans static void
disable_coredumps(void)142062d9380SKyle Evans disable_coredumps(void)
143062d9380SKyle Evans {
144062d9380SKyle Evans struct rlimit rl = { 0 };
145062d9380SKyle Evans
146062d9380SKyle Evans if (setrlimit(RLIMIT_CORE, &rl) == -1)
147062d9380SKyle Evans _exit(EX_OSERR);
148062d9380SKyle Evans }
149062d9380SKyle Evans
150062d9380SKyle Evans /*
151062d9380SKyle Evans * Replaces stdin with a file that we can actually read from, for tests where
152062d9380SKyle Evans * we want a FILE * or fd that we can get data from.
153062d9380SKyle Evans */
154062d9380SKyle Evans static void __unused
replace_stdin(void)155062d9380SKyle Evans replace_stdin(void)
156062d9380SKyle Evans {
157062d9380SKyle Evans int fd;
158062d9380SKyle Evans
159062d9380SKyle Evans fd = new_tmpfile();
160062d9380SKyle Evans
161062d9380SKyle Evans (void)dup2(fd, STDIN_FILENO);
162062d9380SKyle Evans if (fd != STDIN_FILENO)
163062d9380SKyle Evans close(fd);
164062d9380SKyle Evans }
165062d9380SKyle Evans
16609cdbf04SKyle Evans ATF_TC(getrandom_before_end);
ATF_TC_HEAD(getrandom_before_end,tc)16709cdbf04SKyle Evans ATF_TC_HEAD(getrandom_before_end, tc)
16809cdbf04SKyle Evans {
16909cdbf04SKyle Evans }
ATF_TC_BODY(getrandom_before_end,tc)170062d9380SKyle Evans ATF_TC_BODY(getrandom_before_end, tc)
171062d9380SKyle Evans {
172062d9380SKyle Evans #define BUF &__stack.__buf
173062d9380SKyle Evans struct {
174062d9380SKyle Evans uint8_t padding_l;
175062d9380SKyle Evans unsigned char __buf[42];
176062d9380SKyle Evans uint8_t padding_r;
177062d9380SKyle Evans } __stack;
178062d9380SKyle Evans const size_t __bufsz __unused = sizeof(__stack.__buf);
179062d9380SKyle Evans const size_t __len = 42 - 1;
180062d9380SKyle Evans const size_t __idx __unused = __len - 1;
181062d9380SKyle Evans
182062d9380SKyle Evans getrandom(__stack.__buf, __len, 0);
183062d9380SKyle Evans #undef BUF
184062d9380SKyle Evans
185062d9380SKyle Evans }
186062d9380SKyle Evans
18709cdbf04SKyle Evans ATF_TC(getrandom_end);
ATF_TC_HEAD(getrandom_end,tc)18809cdbf04SKyle Evans ATF_TC_HEAD(getrandom_end, tc)
18909cdbf04SKyle Evans {
19009cdbf04SKyle Evans }
ATF_TC_BODY(getrandom_end,tc)191062d9380SKyle Evans ATF_TC_BODY(getrandom_end, tc)
192062d9380SKyle Evans {
193062d9380SKyle Evans #define BUF &__stack.__buf
194062d9380SKyle Evans struct {
195062d9380SKyle Evans uint8_t padding_l;
196062d9380SKyle Evans unsigned char __buf[42];
197062d9380SKyle Evans uint8_t padding_r;
198062d9380SKyle Evans } __stack;
199062d9380SKyle Evans const size_t __bufsz __unused = sizeof(__stack.__buf);
200062d9380SKyle Evans const size_t __len = 42;
201062d9380SKyle Evans const size_t __idx __unused = __len - 1;
202062d9380SKyle Evans
203062d9380SKyle Evans getrandom(__stack.__buf, __len, 0);
204062d9380SKyle Evans #undef BUF
205062d9380SKyle Evans
206062d9380SKyle Evans }
207062d9380SKyle Evans
20809cdbf04SKyle Evans ATF_TC(getrandom_heap_before_end);
ATF_TC_HEAD(getrandom_heap_before_end,tc)20909cdbf04SKyle Evans ATF_TC_HEAD(getrandom_heap_before_end, tc)
21009cdbf04SKyle Evans {
21109cdbf04SKyle Evans }
ATF_TC_BODY(getrandom_heap_before_end,tc)212062d9380SKyle Evans ATF_TC_BODY(getrandom_heap_before_end, tc)
213062d9380SKyle Evans {
214062d9380SKyle Evans #define BUF __stack.__buf
215062d9380SKyle Evans struct {
216062d9380SKyle Evans uint8_t padding_l;
217062d9380SKyle Evans unsigned char * __buf;
218062d9380SKyle Evans uint8_t padding_r;
219062d9380SKyle Evans } __stack;
220062d9380SKyle Evans const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
221062d9380SKyle Evans const size_t __len = 42 - 1;
222062d9380SKyle Evans const size_t __idx __unused = __len - 1;
223062d9380SKyle Evans
224062d9380SKyle Evans __stack.__buf = malloc(__bufsz);
225062d9380SKyle Evans
226062d9380SKyle Evans getrandom(__stack.__buf, __len, 0);
227062d9380SKyle Evans #undef BUF
228062d9380SKyle Evans
229062d9380SKyle Evans }
230062d9380SKyle Evans
23109cdbf04SKyle Evans ATF_TC(getrandom_heap_end);
ATF_TC_HEAD(getrandom_heap_end,tc)23209cdbf04SKyle Evans ATF_TC_HEAD(getrandom_heap_end, tc)
23309cdbf04SKyle Evans {
23409cdbf04SKyle Evans }
ATF_TC_BODY(getrandom_heap_end,tc)235062d9380SKyle Evans ATF_TC_BODY(getrandom_heap_end, tc)
236062d9380SKyle Evans {
237062d9380SKyle Evans #define BUF __stack.__buf
238062d9380SKyle Evans struct {
239062d9380SKyle Evans uint8_t padding_l;
240062d9380SKyle Evans unsigned char * __buf;
241062d9380SKyle Evans uint8_t padding_r;
242062d9380SKyle Evans } __stack;
243062d9380SKyle Evans const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
244062d9380SKyle Evans const size_t __len = 42;
245062d9380SKyle Evans const size_t __idx __unused = __len - 1;
246062d9380SKyle Evans
247062d9380SKyle Evans __stack.__buf = malloc(__bufsz);
248062d9380SKyle Evans
249062d9380SKyle Evans getrandom(__stack.__buf, __len, 0);
250062d9380SKyle Evans #undef BUF
251062d9380SKyle Evans
252062d9380SKyle Evans }
253062d9380SKyle Evans
25409cdbf04SKyle Evans ATF_TC(getrandom_heap_after_end);
ATF_TC_HEAD(getrandom_heap_after_end,tc)25509cdbf04SKyle Evans ATF_TC_HEAD(getrandom_heap_after_end, tc)
25609cdbf04SKyle Evans {
25709cdbf04SKyle Evans }
ATF_TC_BODY(getrandom_heap_after_end,tc)258062d9380SKyle Evans ATF_TC_BODY(getrandom_heap_after_end, tc)
259062d9380SKyle Evans {
260062d9380SKyle Evans #define BUF __stack.__buf
261062d9380SKyle Evans struct {
262062d9380SKyle Evans uint8_t padding_l;
263062d9380SKyle Evans unsigned char * __buf;
264062d9380SKyle Evans uint8_t padding_r;
265062d9380SKyle Evans } __stack;
266062d9380SKyle Evans const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
267062d9380SKyle Evans const size_t __len = 42 + 1;
268062d9380SKyle Evans const size_t __idx __unused = __len - 1;
269062d9380SKyle Evans pid_t __child;
270062d9380SKyle Evans int __status;
271062d9380SKyle Evans
272062d9380SKyle Evans __child = fork();
273062d9380SKyle Evans ATF_REQUIRE(__child >= 0);
274062d9380SKyle Evans if (__child > 0)
275062d9380SKyle Evans goto monitor;
276062d9380SKyle Evans
277062d9380SKyle Evans /* Child */
278062d9380SKyle Evans disable_coredumps();
279062d9380SKyle Evans __stack.__buf = malloc(__bufsz);
280062d9380SKyle Evans
281062d9380SKyle Evans getrandom(__stack.__buf, __len, 0);
282062d9380SKyle Evans _exit(EX_SOFTWARE); /* Should have aborted. */
283062d9380SKyle Evans
284062d9380SKyle Evans monitor:
285062d9380SKyle Evans while (waitpid(__child, &__status, 0) != __child) {
286062d9380SKyle Evans ATF_REQUIRE_EQ(EINTR, errno);
287062d9380SKyle Evans }
288062d9380SKyle Evans
289062d9380SKyle Evans if (!WIFSIGNALED(__status)) {
290062d9380SKyle Evans switch (WEXITSTATUS(__status)) {
291062d9380SKyle Evans case EX_SOFTWARE:
292062d9380SKyle Evans atf_tc_fail("FORTIFY_SOURCE failed to abort");
293062d9380SKyle Evans break;
294062d9380SKyle Evans case EX_OSERR:
295062d9380SKyle Evans atf_tc_fail("setrlimit(2) failed");
296062d9380SKyle Evans break;
297062d9380SKyle Evans default:
298062d9380SKyle Evans atf_tc_fail("child exited with status %d",
299062d9380SKyle Evans WEXITSTATUS(__status));
300062d9380SKyle Evans }
301062d9380SKyle Evans } else {
302062d9380SKyle Evans ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
303062d9380SKyle Evans }
304062d9380SKyle Evans #undef BUF
305062d9380SKyle Evans
306062d9380SKyle Evans }
307062d9380SKyle Evans
ATF_TP_ADD_TCS(tp)308062d9380SKyle Evans ATF_TP_ADD_TCS(tp)
309062d9380SKyle Evans {
310062d9380SKyle Evans ATF_TP_ADD_TC(tp, getrandom_before_end);
311062d9380SKyle Evans ATF_TP_ADD_TC(tp, getrandom_end);
312062d9380SKyle Evans ATF_TP_ADD_TC(tp, getrandom_heap_before_end);
313062d9380SKyle Evans ATF_TP_ADD_TC(tp, getrandom_heap_end);
314062d9380SKyle Evans ATF_TP_ADD_TC(tp, getrandom_heap_after_end);
315062d9380SKyle Evans return (atf_no_error());
316062d9380SKyle Evans }
317