xref: /freebsd/lib/libc/tests/secure/fortify_stdlib_test.c (revision 873420ca1e6e8a2459684f5b5d3e557a8ef75928)
1d0b74459SKyle Evans /* @generated by `generate-fortify-tests.lua "stdlib"` */
2d0b74459SKyle Evans 
3d0b74459SKyle Evans #define	_FORTIFY_SOURCE	2
4d0b74459SKyle Evans #define	TMPFILE_SIZE	(1024 * 32)
5d0b74459SKyle Evans 
6d0b74459SKyle Evans #include <sys/param.h>
722178cb2SKyle Evans #include <sys/jail.h>
8062d9380SKyle Evans #include <sys/random.h>
9d0b74459SKyle Evans #include <sys/resource.h>
102aba0eeaSKyle Evans #include <sys/select.h>
111f155d48SKyle Evans #include <sys/socket.h>
12d0b74459SKyle Evans #include <sys/time.h>
131ace24b3SKyle Evans #include <sys/uio.h>
14d0b74459SKyle Evans #include <sys/wait.h>
15d0b74459SKyle Evans #include <dirent.h>
16d0b74459SKyle Evans #include <errno.h>
17d0b74459SKyle Evans #include <fcntl.h>
18d0b74459SKyle Evans #include <limits.h>
19d0b74459SKyle Evans #include <poll.h>
20d0b74459SKyle Evans #include <signal.h>
21d0b74459SKyle Evans #include <stdio.h>
22d0b74459SKyle Evans #include <stdlib.h>
23d0b74459SKyle Evans #include <string.h>
24d0b74459SKyle Evans #include <strings.h>
25d0b74459SKyle Evans #include <sysexits.h>
26d0b74459SKyle Evans #include <unistd.h>
27b53d7aa8SKyle Evans #include <wchar.h>
28d0b74459SKyle Evans #include <atf-c.h>
29d0b74459SKyle Evans 
30d0b74459SKyle Evans static FILE * __unused
31d0b74459SKyle Evans new_fp(size_t __len)
32d0b74459SKyle Evans {
33d0b74459SKyle Evans 	static char fpbuf[LINE_MAX];
34d0b74459SKyle Evans 	FILE *fp;
35d0b74459SKyle Evans 
36d0b74459SKyle Evans 	ATF_REQUIRE(__len <= sizeof(fpbuf));
37d0b74459SKyle Evans 
38d0b74459SKyle Evans 	memset(fpbuf, 'A', sizeof(fpbuf) - 1);
39d0b74459SKyle Evans 	fpbuf[sizeof(fpbuf) - 1] = '\0';
40d0b74459SKyle Evans 
41d0b74459SKyle Evans 	fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
42d0b74459SKyle Evans 	ATF_REQUIRE(fp != NULL);
43d0b74459SKyle Evans 
44d0b74459SKyle Evans 	return (fp);
45d0b74459SKyle Evans }
46d0b74459SKyle Evans 
47d0b74459SKyle Evans /*
48d0b74459SKyle Evans  * Create a new symlink to use for readlink(2) style tests, we'll just use a
49d0b74459SKyle Evans  * random target name to have something interesting to look at.
50d0b74459SKyle Evans  */
51d0b74459SKyle Evans static const char * __unused
52d0b74459SKyle Evans new_symlink(size_t __len)
53d0b74459SKyle Evans {
54d0b74459SKyle Evans 	static const char linkname[] = "link";
55d0b74459SKyle Evans 	char target[MAXNAMLEN];
56d0b74459SKyle Evans 	int error;
57d0b74459SKyle Evans 
58d0b74459SKyle Evans 	ATF_REQUIRE(__len <= sizeof(target));
59d0b74459SKyle Evans 
60d0b74459SKyle Evans 	arc4random_buf(target, sizeof(target));
61d0b74459SKyle Evans 
62d0b74459SKyle Evans 	error = unlink(linkname);
63d0b74459SKyle Evans 	ATF_REQUIRE(error == 0 || errno == ENOENT);
64d0b74459SKyle Evans 
65d0b74459SKyle Evans 	error = symlink(target, linkname);
66d0b74459SKyle Evans 	ATF_REQUIRE(error == 0);
67d0b74459SKyle Evans 
68d0b74459SKyle Evans 	return (linkname);
69d0b74459SKyle Evans }
70d0b74459SKyle Evans 
71d0b74459SKyle 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
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 /*
116d0b74459SKyle Evans  * Constructs a tmpfile that we can use for testing read(2) and friends.
117d0b74459SKyle Evans  */
118d0b74459SKyle Evans static int __unused
119d0b74459SKyle Evans new_tmpfile(void)
120d0b74459SKyle Evans {
121d0b74459SKyle Evans 	char buf[1024];
122d0b74459SKyle Evans 	ssize_t rv;
123d0b74459SKyle Evans 	size_t written;
124d0b74459SKyle Evans 	int fd;
125d0b74459SKyle Evans 
126d0b74459SKyle Evans 	fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
127d0b74459SKyle Evans 	ATF_REQUIRE(fd >= 0);
128d0b74459SKyle Evans 
129d0b74459SKyle Evans 	written = 0;
130d0b74459SKyle Evans 	while (written < TMPFILE_SIZE) {
131d0b74459SKyle Evans 		rv = write(fd, buf, sizeof(buf));
132d0b74459SKyle Evans 		ATF_REQUIRE(rv > 0);
133d0b74459SKyle Evans 
134d0b74459SKyle Evans 		written += rv;
135d0b74459SKyle Evans 	}
136d0b74459SKyle Evans 
137d0b74459SKyle Evans 	ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
138d0b74459SKyle Evans 	return (fd);
139d0b74459SKyle Evans }
140d0b74459SKyle Evans 
141d0b74459SKyle Evans static void
142d0b74459SKyle Evans disable_coredumps(void)
143d0b74459SKyle Evans {
144d0b74459SKyle Evans 	struct rlimit rl = { 0 };
145d0b74459SKyle Evans 
146d0b74459SKyle Evans 	if (setrlimit(RLIMIT_CORE, &rl) == -1)
147d0b74459SKyle Evans 		_exit(EX_OSERR);
148d0b74459SKyle Evans }
149d0b74459SKyle Evans 
150d0b74459SKyle Evans /*
151d0b74459SKyle Evans  * Replaces stdin with a file that we can actually read from, for tests where
152d0b74459SKyle Evans  * we want a FILE * or fd that we can get data from.
153d0b74459SKyle Evans  */
154d0b74459SKyle Evans static void __unused
155d0b74459SKyle Evans replace_stdin(void)
156d0b74459SKyle Evans {
157d0b74459SKyle Evans 	int fd;
158d0b74459SKyle Evans 
159d0b74459SKyle Evans 	fd = new_tmpfile();
160d0b74459SKyle Evans 
161d0b74459SKyle Evans 	(void)dup2(fd, STDIN_FILENO);
162d0b74459SKyle Evans 	if (fd != STDIN_FILENO)
163d0b74459SKyle Evans 		close(fd);
164d0b74459SKyle Evans }
165d0b74459SKyle Evans 
16609cdbf04SKyle Evans ATF_TC(arc4random_buf_before_end);
16709cdbf04SKyle Evans ATF_TC_HEAD(arc4random_buf_before_end, tc)
16809cdbf04SKyle Evans {
16909cdbf04SKyle Evans }
170d0b74459SKyle Evans ATF_TC_BODY(arc4random_buf_before_end, tc)
171d0b74459SKyle Evans {
172d0b74459SKyle Evans #define BUF &__stack.__buf
173d0b74459SKyle Evans 	struct {
174d0b74459SKyle Evans 		uint8_t padding_l;
175d0b74459SKyle Evans 		unsigned char __buf[42];
176d0b74459SKyle Evans 		uint8_t padding_r;
177d0b74459SKyle Evans 	} __stack;
178d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
179d0b74459SKyle Evans 	const size_t __len = 42 - 1;
180d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
181d0b74459SKyle Evans 
182d0b74459SKyle Evans 	arc4random_buf(__stack.__buf, __len);
183d0b74459SKyle Evans #undef BUF
184d0b74459SKyle Evans 
185d0b74459SKyle Evans }
186d0b74459SKyle Evans 
18709cdbf04SKyle Evans ATF_TC(arc4random_buf_end);
18809cdbf04SKyle Evans ATF_TC_HEAD(arc4random_buf_end, tc)
18909cdbf04SKyle Evans {
19009cdbf04SKyle Evans }
191d0b74459SKyle Evans ATF_TC_BODY(arc4random_buf_end, tc)
192d0b74459SKyle Evans {
193d0b74459SKyle Evans #define BUF &__stack.__buf
194d0b74459SKyle Evans 	struct {
195d0b74459SKyle Evans 		uint8_t padding_l;
196d0b74459SKyle Evans 		unsigned char __buf[42];
197d0b74459SKyle Evans 		uint8_t padding_r;
198d0b74459SKyle Evans 	} __stack;
199d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
200d0b74459SKyle Evans 	const size_t __len = 42;
201d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
202d0b74459SKyle Evans 
203d0b74459SKyle Evans 	arc4random_buf(__stack.__buf, __len);
204d0b74459SKyle Evans #undef BUF
205d0b74459SKyle Evans 
206d0b74459SKyle Evans }
207d0b74459SKyle Evans 
20809cdbf04SKyle Evans ATF_TC(arc4random_buf_heap_before_end);
20909cdbf04SKyle Evans ATF_TC_HEAD(arc4random_buf_heap_before_end, tc)
21009cdbf04SKyle Evans {
21109cdbf04SKyle Evans }
212d0b74459SKyle Evans ATF_TC_BODY(arc4random_buf_heap_before_end, tc)
213d0b74459SKyle Evans {
214d0b74459SKyle Evans #define BUF __stack.__buf
215d0b74459SKyle Evans 	struct {
216d0b74459SKyle Evans 		uint8_t padding_l;
217d0b74459SKyle Evans 		unsigned char * __buf;
218d0b74459SKyle Evans 		uint8_t padding_r;
219d0b74459SKyle Evans 	} __stack;
220d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
221d0b74459SKyle Evans 	const size_t __len = 42 - 1;
222d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
223d0b74459SKyle Evans 
224d0b74459SKyle Evans 	__stack.__buf = malloc(__bufsz);
225d0b74459SKyle Evans 
226d0b74459SKyle Evans 	arc4random_buf(__stack.__buf, __len);
227d0b74459SKyle Evans #undef BUF
228d0b74459SKyle Evans 
229d0b74459SKyle Evans }
230d0b74459SKyle Evans 
23109cdbf04SKyle Evans ATF_TC(arc4random_buf_heap_end);
23209cdbf04SKyle Evans ATF_TC_HEAD(arc4random_buf_heap_end, tc)
23309cdbf04SKyle Evans {
23409cdbf04SKyle Evans }
235d0b74459SKyle Evans ATF_TC_BODY(arc4random_buf_heap_end, tc)
236d0b74459SKyle Evans {
237d0b74459SKyle Evans #define BUF __stack.__buf
238d0b74459SKyle Evans 	struct {
239d0b74459SKyle Evans 		uint8_t padding_l;
240d0b74459SKyle Evans 		unsigned char * __buf;
241d0b74459SKyle Evans 		uint8_t padding_r;
242d0b74459SKyle Evans 	} __stack;
243d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
244d0b74459SKyle Evans 	const size_t __len = 42;
245d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
246d0b74459SKyle Evans 
247d0b74459SKyle Evans 	__stack.__buf = malloc(__bufsz);
248d0b74459SKyle Evans 
249d0b74459SKyle Evans 	arc4random_buf(__stack.__buf, __len);
250d0b74459SKyle Evans #undef BUF
251d0b74459SKyle Evans 
252d0b74459SKyle Evans }
253d0b74459SKyle Evans 
25409cdbf04SKyle Evans ATF_TC(arc4random_buf_heap_after_end);
25509cdbf04SKyle Evans ATF_TC_HEAD(arc4random_buf_heap_after_end, tc)
25609cdbf04SKyle Evans {
25709cdbf04SKyle Evans }
258d0b74459SKyle Evans ATF_TC_BODY(arc4random_buf_heap_after_end, tc)
259d0b74459SKyle Evans {
260d0b74459SKyle Evans #define BUF __stack.__buf
261d0b74459SKyle Evans 	struct {
262d0b74459SKyle Evans 		uint8_t padding_l;
263d0b74459SKyle Evans 		unsigned char * __buf;
264d0b74459SKyle Evans 		uint8_t padding_r;
265d0b74459SKyle Evans 	} __stack;
266d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
267d0b74459SKyle Evans 	const size_t __len = 42 + 1;
268d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
269d0b74459SKyle Evans 	pid_t __child;
270d0b74459SKyle Evans 	int __status;
271d0b74459SKyle Evans 
272d0b74459SKyle Evans 	__child = fork();
273d0b74459SKyle Evans 	ATF_REQUIRE(__child >= 0);
274d0b74459SKyle Evans 	if (__child > 0)
275d0b74459SKyle Evans 		goto monitor;
276d0b74459SKyle Evans 
277d0b74459SKyle Evans 	/* Child */
278d0b74459SKyle Evans 	disable_coredumps();
279d0b74459SKyle Evans 	__stack.__buf = malloc(__bufsz);
280d0b74459SKyle Evans 
281d0b74459SKyle Evans 	arc4random_buf(__stack.__buf, __len);
282d0b74459SKyle Evans 	_exit(EX_SOFTWARE);	/* Should have aborted. */
283d0b74459SKyle Evans 
284d0b74459SKyle Evans monitor:
285d0b74459SKyle Evans 	while (waitpid(__child, &__status, 0) != __child) {
286d0b74459SKyle Evans 		ATF_REQUIRE_EQ(EINTR, errno);
287d0b74459SKyle Evans 	}
288d0b74459SKyle Evans 
289d0b74459SKyle Evans 	if (!WIFSIGNALED(__status)) {
290d0b74459SKyle Evans 		switch (WEXITSTATUS(__status)) {
291d0b74459SKyle Evans 		case EX_SOFTWARE:
292d0b74459SKyle Evans 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
293d0b74459SKyle Evans 			break;
294d0b74459SKyle Evans 		case EX_OSERR:
295d0b74459SKyle Evans 			atf_tc_fail("setrlimit(2) failed");
296d0b74459SKyle Evans 			break;
297d0b74459SKyle Evans 		default:
298d0b74459SKyle Evans 			atf_tc_fail("child exited with status %d",
299d0b74459SKyle Evans 			    WEXITSTATUS(__status));
300d0b74459SKyle Evans 		}
301d0b74459SKyle Evans 	} else {
302d0b74459SKyle Evans 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
303d0b74459SKyle Evans 	}
304d0b74459SKyle Evans #undef BUF
305d0b74459SKyle Evans 
306d0b74459SKyle Evans }
307d0b74459SKyle Evans 
308*873420caSDag-Erling Smørgrav ATF_TC(getenv_r_before_end);
309*873420caSDag-Erling Smørgrav ATF_TC_HEAD(getenv_r_before_end, tc)
310*873420caSDag-Erling Smørgrav {
311*873420caSDag-Erling Smørgrav }
312*873420caSDag-Erling Smørgrav ATF_TC_BODY(getenv_r_before_end, tc)
313*873420caSDag-Erling Smørgrav {
314*873420caSDag-Erling Smørgrav #define BUF &__stack.__buf
315*873420caSDag-Erling Smørgrav 	struct {
316*873420caSDag-Erling Smørgrav 		uint8_t padding_l;
317*873420caSDag-Erling Smørgrav 		unsigned char __buf[42];
318*873420caSDag-Erling Smørgrav 		uint8_t padding_r;
319*873420caSDag-Erling Smørgrav 	} __stack;
320*873420caSDag-Erling Smørgrav 	const size_t __bufsz __unused = sizeof(__stack.__buf);
321*873420caSDag-Erling Smørgrav 	const size_t __len = 42 - 1;
322*873420caSDag-Erling Smørgrav 	const size_t __idx __unused = __len - 1;
323*873420caSDag-Erling Smørgrav 
324*873420caSDag-Erling Smørgrav 	getenv_r("PATH", __stack.__buf, __len);
325*873420caSDag-Erling Smørgrav #undef BUF
326*873420caSDag-Erling Smørgrav 
327*873420caSDag-Erling Smørgrav }
328*873420caSDag-Erling Smørgrav 
329*873420caSDag-Erling Smørgrav ATF_TC(getenv_r_end);
330*873420caSDag-Erling Smørgrav ATF_TC_HEAD(getenv_r_end, tc)
331*873420caSDag-Erling Smørgrav {
332*873420caSDag-Erling Smørgrav }
333*873420caSDag-Erling Smørgrav ATF_TC_BODY(getenv_r_end, tc)
334*873420caSDag-Erling Smørgrav {
335*873420caSDag-Erling Smørgrav #define BUF &__stack.__buf
336*873420caSDag-Erling Smørgrav 	struct {
337*873420caSDag-Erling Smørgrav 		uint8_t padding_l;
338*873420caSDag-Erling Smørgrav 		unsigned char __buf[42];
339*873420caSDag-Erling Smørgrav 		uint8_t padding_r;
340*873420caSDag-Erling Smørgrav 	} __stack;
341*873420caSDag-Erling Smørgrav 	const size_t __bufsz __unused = sizeof(__stack.__buf);
342*873420caSDag-Erling Smørgrav 	const size_t __len = 42;
343*873420caSDag-Erling Smørgrav 	const size_t __idx __unused = __len - 1;
344*873420caSDag-Erling Smørgrav 
345*873420caSDag-Erling Smørgrav 	getenv_r("PATH", __stack.__buf, __len);
346*873420caSDag-Erling Smørgrav #undef BUF
347*873420caSDag-Erling Smørgrav 
348*873420caSDag-Erling Smørgrav }
349*873420caSDag-Erling Smørgrav 
350*873420caSDag-Erling Smørgrav ATF_TC(getenv_r_heap_before_end);
351*873420caSDag-Erling Smørgrav ATF_TC_HEAD(getenv_r_heap_before_end, tc)
352*873420caSDag-Erling Smørgrav {
353*873420caSDag-Erling Smørgrav }
354*873420caSDag-Erling Smørgrav ATF_TC_BODY(getenv_r_heap_before_end, tc)
355*873420caSDag-Erling Smørgrav {
356*873420caSDag-Erling Smørgrav #define BUF __stack.__buf
357*873420caSDag-Erling Smørgrav 	struct {
358*873420caSDag-Erling Smørgrav 		uint8_t padding_l;
359*873420caSDag-Erling Smørgrav 		unsigned char * __buf;
360*873420caSDag-Erling Smørgrav 		uint8_t padding_r;
361*873420caSDag-Erling Smørgrav 	} __stack;
362*873420caSDag-Erling Smørgrav 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
363*873420caSDag-Erling Smørgrav 	const size_t __len = 42 - 1;
364*873420caSDag-Erling Smørgrav 	const size_t __idx __unused = __len - 1;
365*873420caSDag-Erling Smørgrav 
366*873420caSDag-Erling Smørgrav 	__stack.__buf = malloc(__bufsz);
367*873420caSDag-Erling Smørgrav 
368*873420caSDag-Erling Smørgrav 	getenv_r("PATH", __stack.__buf, __len);
369*873420caSDag-Erling Smørgrav #undef BUF
370*873420caSDag-Erling Smørgrav 
371*873420caSDag-Erling Smørgrav }
372*873420caSDag-Erling Smørgrav 
373*873420caSDag-Erling Smørgrav ATF_TC(getenv_r_heap_end);
374*873420caSDag-Erling Smørgrav ATF_TC_HEAD(getenv_r_heap_end, tc)
375*873420caSDag-Erling Smørgrav {
376*873420caSDag-Erling Smørgrav }
377*873420caSDag-Erling Smørgrav ATF_TC_BODY(getenv_r_heap_end, tc)
378*873420caSDag-Erling Smørgrav {
379*873420caSDag-Erling Smørgrav #define BUF __stack.__buf
380*873420caSDag-Erling Smørgrav 	struct {
381*873420caSDag-Erling Smørgrav 		uint8_t padding_l;
382*873420caSDag-Erling Smørgrav 		unsigned char * __buf;
383*873420caSDag-Erling Smørgrav 		uint8_t padding_r;
384*873420caSDag-Erling Smørgrav 	} __stack;
385*873420caSDag-Erling Smørgrav 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
386*873420caSDag-Erling Smørgrav 	const size_t __len = 42;
387*873420caSDag-Erling Smørgrav 	const size_t __idx __unused = __len - 1;
388*873420caSDag-Erling Smørgrav 
389*873420caSDag-Erling Smørgrav 	__stack.__buf = malloc(__bufsz);
390*873420caSDag-Erling Smørgrav 
391*873420caSDag-Erling Smørgrav 	getenv_r("PATH", __stack.__buf, __len);
392*873420caSDag-Erling Smørgrav #undef BUF
393*873420caSDag-Erling Smørgrav 
394*873420caSDag-Erling Smørgrav }
395*873420caSDag-Erling Smørgrav 
396*873420caSDag-Erling Smørgrav ATF_TC(getenv_r_heap_after_end);
397*873420caSDag-Erling Smørgrav ATF_TC_HEAD(getenv_r_heap_after_end, tc)
398*873420caSDag-Erling Smørgrav {
399*873420caSDag-Erling Smørgrav }
400*873420caSDag-Erling Smørgrav ATF_TC_BODY(getenv_r_heap_after_end, tc)
401*873420caSDag-Erling Smørgrav {
402*873420caSDag-Erling Smørgrav #define BUF __stack.__buf
403*873420caSDag-Erling Smørgrav 	struct {
404*873420caSDag-Erling Smørgrav 		uint8_t padding_l;
405*873420caSDag-Erling Smørgrav 		unsigned char * __buf;
406*873420caSDag-Erling Smørgrav 		uint8_t padding_r;
407*873420caSDag-Erling Smørgrav 	} __stack;
408*873420caSDag-Erling Smørgrav 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
409*873420caSDag-Erling Smørgrav 	const size_t __len = 42 + 1;
410*873420caSDag-Erling Smørgrav 	const size_t __idx __unused = __len - 1;
411*873420caSDag-Erling Smørgrav 	pid_t __child;
412*873420caSDag-Erling Smørgrav 	int __status;
413*873420caSDag-Erling Smørgrav 
414*873420caSDag-Erling Smørgrav 	__child = fork();
415*873420caSDag-Erling Smørgrav 	ATF_REQUIRE(__child >= 0);
416*873420caSDag-Erling Smørgrav 	if (__child > 0)
417*873420caSDag-Erling Smørgrav 		goto monitor;
418*873420caSDag-Erling Smørgrav 
419*873420caSDag-Erling Smørgrav 	/* Child */
420*873420caSDag-Erling Smørgrav 	disable_coredumps();
421*873420caSDag-Erling Smørgrav 	__stack.__buf = malloc(__bufsz);
422*873420caSDag-Erling Smørgrav 
423*873420caSDag-Erling Smørgrav 	getenv_r("PATH", __stack.__buf, __len);
424*873420caSDag-Erling Smørgrav 	_exit(EX_SOFTWARE);	/* Should have aborted. */
425*873420caSDag-Erling Smørgrav 
426*873420caSDag-Erling Smørgrav monitor:
427*873420caSDag-Erling Smørgrav 	while (waitpid(__child, &__status, 0) != __child) {
428*873420caSDag-Erling Smørgrav 		ATF_REQUIRE_EQ(EINTR, errno);
429*873420caSDag-Erling Smørgrav 	}
430*873420caSDag-Erling Smørgrav 
431*873420caSDag-Erling Smørgrav 	if (!WIFSIGNALED(__status)) {
432*873420caSDag-Erling Smørgrav 		switch (WEXITSTATUS(__status)) {
433*873420caSDag-Erling Smørgrav 		case EX_SOFTWARE:
434*873420caSDag-Erling Smørgrav 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
435*873420caSDag-Erling Smørgrav 			break;
436*873420caSDag-Erling Smørgrav 		case EX_OSERR:
437*873420caSDag-Erling Smørgrav 			atf_tc_fail("setrlimit(2) failed");
438*873420caSDag-Erling Smørgrav 			break;
439*873420caSDag-Erling Smørgrav 		default:
440*873420caSDag-Erling Smørgrav 			atf_tc_fail("child exited with status %d",
441*873420caSDag-Erling Smørgrav 			    WEXITSTATUS(__status));
442*873420caSDag-Erling Smørgrav 		}
443*873420caSDag-Erling Smørgrav 	} else {
444*873420caSDag-Erling Smørgrav 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
445*873420caSDag-Erling Smørgrav 	}
446*873420caSDag-Erling Smørgrav #undef BUF
447*873420caSDag-Erling Smørgrav 
448*873420caSDag-Erling Smørgrav }
449*873420caSDag-Erling Smørgrav 
45009cdbf04SKyle Evans ATF_TC(realpath_before_end);
45109cdbf04SKyle Evans ATF_TC_HEAD(realpath_before_end, tc)
45209cdbf04SKyle Evans {
45309cdbf04SKyle Evans }
454d0b74459SKyle Evans ATF_TC_BODY(realpath_before_end, tc)
455d0b74459SKyle Evans {
456d0b74459SKyle Evans #define BUF &__stack.__buf
457d0b74459SKyle Evans 	struct {
458d0b74459SKyle Evans 		uint8_t padding_l;
459d0b74459SKyle Evans 		unsigned char __buf[PATH_MAX + 1];
460d0b74459SKyle Evans 		uint8_t padding_r;
461d0b74459SKyle Evans 	} __stack;
462d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
463d0b74459SKyle Evans 	const size_t __len = PATH_MAX + 1;
464d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
465d0b74459SKyle Evans 
466d0b74459SKyle Evans 	realpath(".", __stack.__buf);
467d0b74459SKyle Evans #undef BUF
468d0b74459SKyle Evans 
469d0b74459SKyle Evans }
470d0b74459SKyle Evans 
47109cdbf04SKyle Evans ATF_TC(realpath_end);
47209cdbf04SKyle Evans ATF_TC_HEAD(realpath_end, tc)
47309cdbf04SKyle Evans {
47409cdbf04SKyle Evans }
475d0b74459SKyle Evans ATF_TC_BODY(realpath_end, tc)
476d0b74459SKyle Evans {
477d0b74459SKyle Evans #define BUF &__stack.__buf
478d0b74459SKyle Evans 	struct {
479d0b74459SKyle Evans 		uint8_t padding_l;
480d0b74459SKyle Evans 		unsigned char __buf[PATH_MAX];
481d0b74459SKyle Evans 		uint8_t padding_r;
482d0b74459SKyle Evans 	} __stack;
483d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
484d0b74459SKyle Evans 	const size_t __len = PATH_MAX;
485d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
486d0b74459SKyle Evans 
487d0b74459SKyle Evans 	realpath(".", __stack.__buf);
488d0b74459SKyle Evans #undef BUF
489d0b74459SKyle Evans 
490d0b74459SKyle Evans }
491d0b74459SKyle Evans 
49209cdbf04SKyle Evans ATF_TC(realpath_heap_before_end);
49309cdbf04SKyle Evans ATF_TC_HEAD(realpath_heap_before_end, tc)
49409cdbf04SKyle Evans {
49509cdbf04SKyle Evans }
496d0b74459SKyle Evans ATF_TC_BODY(realpath_heap_before_end, tc)
497d0b74459SKyle Evans {
498d0b74459SKyle Evans #define BUF __stack.__buf
499d0b74459SKyle Evans 	struct {
500d0b74459SKyle Evans 		uint8_t padding_l;
501d0b74459SKyle Evans 		unsigned char * __buf;
502d0b74459SKyle Evans 		uint8_t padding_r;
503d0b74459SKyle Evans 	} __stack;
504d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX + 1);
505d0b74459SKyle Evans 	const size_t __len = PATH_MAX + 1;
506d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
507d0b74459SKyle Evans 
508d0b74459SKyle Evans 	__stack.__buf = malloc(__bufsz);
509d0b74459SKyle Evans 
510d0b74459SKyle Evans 	realpath(".", __stack.__buf);
511d0b74459SKyle Evans #undef BUF
512d0b74459SKyle Evans 
513d0b74459SKyle Evans }
514d0b74459SKyle Evans 
51509cdbf04SKyle Evans ATF_TC(realpath_heap_end);
51609cdbf04SKyle Evans ATF_TC_HEAD(realpath_heap_end, tc)
51709cdbf04SKyle Evans {
51809cdbf04SKyle Evans }
519d0b74459SKyle Evans ATF_TC_BODY(realpath_heap_end, tc)
520d0b74459SKyle Evans {
521d0b74459SKyle Evans #define BUF __stack.__buf
522d0b74459SKyle Evans 	struct {
523d0b74459SKyle Evans 		uint8_t padding_l;
524d0b74459SKyle Evans 		unsigned char * __buf;
525d0b74459SKyle Evans 		uint8_t padding_r;
526d0b74459SKyle Evans 	} __stack;
527d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX);
528d0b74459SKyle Evans 	const size_t __len = PATH_MAX;
529d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
530d0b74459SKyle Evans 
531d0b74459SKyle Evans 	__stack.__buf = malloc(__bufsz);
532d0b74459SKyle Evans 
533d0b74459SKyle Evans 	realpath(".", __stack.__buf);
534d0b74459SKyle Evans #undef BUF
535d0b74459SKyle Evans 
536d0b74459SKyle Evans }
537d0b74459SKyle Evans 
53809cdbf04SKyle Evans ATF_TC(realpath_heap_after_end);
53909cdbf04SKyle Evans ATF_TC_HEAD(realpath_heap_after_end, tc)
54009cdbf04SKyle Evans {
54109cdbf04SKyle Evans }
542d0b74459SKyle Evans ATF_TC_BODY(realpath_heap_after_end, tc)
543d0b74459SKyle Evans {
544d0b74459SKyle Evans #define BUF __stack.__buf
545d0b74459SKyle Evans 	struct {
546d0b74459SKyle Evans 		uint8_t padding_l;
547d0b74459SKyle Evans 		unsigned char * __buf;
548d0b74459SKyle Evans 		uint8_t padding_r;
549d0b74459SKyle Evans 	} __stack;
550d0b74459SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX - 1);
551d0b74459SKyle Evans 	const size_t __len = PATH_MAX - 1;
552d0b74459SKyle Evans 	const size_t __idx __unused = __len - 1;
553d0b74459SKyle Evans 	pid_t __child;
554d0b74459SKyle Evans 	int __status;
555d0b74459SKyle Evans 
556d0b74459SKyle Evans 	__child = fork();
557d0b74459SKyle Evans 	ATF_REQUIRE(__child >= 0);
558d0b74459SKyle Evans 	if (__child > 0)
559d0b74459SKyle Evans 		goto monitor;
560d0b74459SKyle Evans 
561d0b74459SKyle Evans 	/* Child */
562d0b74459SKyle Evans 	disable_coredumps();
563d0b74459SKyle Evans 	__stack.__buf = malloc(__bufsz);
564d0b74459SKyle Evans 
565d0b74459SKyle Evans 	realpath(".", __stack.__buf);
566d0b74459SKyle Evans 	_exit(EX_SOFTWARE);	/* Should have aborted. */
567d0b74459SKyle Evans 
568d0b74459SKyle Evans monitor:
569d0b74459SKyle Evans 	while (waitpid(__child, &__status, 0) != __child) {
570d0b74459SKyle Evans 		ATF_REQUIRE_EQ(EINTR, errno);
571d0b74459SKyle Evans 	}
572d0b74459SKyle Evans 
573d0b74459SKyle Evans 	if (!WIFSIGNALED(__status)) {
574d0b74459SKyle Evans 		switch (WEXITSTATUS(__status)) {
575d0b74459SKyle Evans 		case EX_SOFTWARE:
576d0b74459SKyle Evans 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
577d0b74459SKyle Evans 			break;
578d0b74459SKyle Evans 		case EX_OSERR:
579d0b74459SKyle Evans 			atf_tc_fail("setrlimit(2) failed");
580d0b74459SKyle Evans 			break;
581d0b74459SKyle Evans 		default:
582d0b74459SKyle Evans 			atf_tc_fail("child exited with status %d",
583d0b74459SKyle Evans 			    WEXITSTATUS(__status));
584d0b74459SKyle Evans 		}
585d0b74459SKyle Evans 	} else {
586d0b74459SKyle Evans 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
587d0b74459SKyle Evans 	}
588d0b74459SKyle Evans #undef BUF
589d0b74459SKyle Evans 
590d0b74459SKyle Evans }
591d0b74459SKyle Evans 
592d0b74459SKyle Evans ATF_TP_ADD_TCS(tp)
593d0b74459SKyle Evans {
594d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, arc4random_buf_before_end);
595d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, arc4random_buf_end);
596d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, arc4random_buf_heap_before_end);
597d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, arc4random_buf_heap_end);
598d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, arc4random_buf_heap_after_end);
599*873420caSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, getenv_r_before_end);
600*873420caSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, getenv_r_end);
601*873420caSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, getenv_r_heap_before_end);
602*873420caSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, getenv_r_heap_end);
603*873420caSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, getenv_r_heap_after_end);
604d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, realpath_before_end);
605d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, realpath_end);
606d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, realpath_heap_before_end);
607d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, realpath_heap_end);
608d0b74459SKyle Evans 	ATF_TP_ADD_TC(tp, realpath_heap_after_end);
609d0b74459SKyle Evans 	return (atf_no_error());
610d0b74459SKyle Evans }
611