xref: /freebsd/lib/libc/tests/secure/fortify_strings_test.c (revision 22178cb29f03a3b7bf919f3605e0cd5d6b18fa0a)
1020d003cSKyle Evans /* @generated by `generate-fortify-tests.lua "strings"` */
2020d003cSKyle Evans 
3020d003cSKyle Evans #define	_FORTIFY_SOURCE	2
4020d003cSKyle Evans #define	TMPFILE_SIZE	(1024 * 32)
5020d003cSKyle Evans 
6020d003cSKyle Evans #include <sys/param.h>
7*22178cb2SKyle Evans #include <sys/jail.h>
8062d9380SKyle Evans #include <sys/random.h>
9020d003cSKyle Evans #include <sys/resource.h>
102aba0eeaSKyle Evans #include <sys/select.h>
111f155d48SKyle Evans #include <sys/socket.h>
12020d003cSKyle Evans #include <sys/time.h>
131ace24b3SKyle Evans #include <sys/uio.h>
14020d003cSKyle Evans #include <sys/wait.h>
15020d003cSKyle Evans #include <dirent.h>
16020d003cSKyle Evans #include <errno.h>
17020d003cSKyle Evans #include <fcntl.h>
18020d003cSKyle Evans #include <limits.h>
1988276dfbSKyle Evans #include <poll.h>
20020d003cSKyle Evans #include <signal.h>
21020d003cSKyle Evans #include <stdio.h>
22020d003cSKyle Evans #include <stdlib.h>
23020d003cSKyle Evans #include <string.h>
24020d003cSKyle Evans #include <strings.h>
25020d003cSKyle Evans #include <sysexits.h>
26020d003cSKyle Evans #include <unistd.h>
27b53d7aa8SKyle Evans #include <wchar.h>
28020d003cSKyle Evans #include <atf-c.h>
29020d003cSKyle Evans 
30cf8e5289SKyle Evans static FILE * __unused
new_fp(size_t __len)31cf8e5289SKyle Evans new_fp(size_t __len)
32cf8e5289SKyle Evans {
33cf8e5289SKyle Evans 	static char fpbuf[LINE_MAX];
34cf8e5289SKyle Evans 	FILE *fp;
35cf8e5289SKyle Evans 
36cf8e5289SKyle Evans 	ATF_REQUIRE(__len <= sizeof(fpbuf));
37cf8e5289SKyle Evans 
38cf8e5289SKyle Evans 	memset(fpbuf, 'A', sizeof(fpbuf) - 1);
39cf8e5289SKyle Evans 	fpbuf[sizeof(fpbuf) - 1] = '\0';
40cf8e5289SKyle Evans 
41cf8e5289SKyle Evans 	fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
42cf8e5289SKyle Evans 	ATF_REQUIRE(fp != NULL);
43cf8e5289SKyle Evans 
44cf8e5289SKyle Evans 	return (fp);
45cf8e5289SKyle Evans }
46cf8e5289SKyle Evans 
47020d003cSKyle Evans /*
48020d003cSKyle Evans  * Create a new symlink to use for readlink(2) style tests, we'll just use a
49020d003cSKyle Evans  * random target name to have something interesting to look at.
50020d003cSKyle Evans  */
51020d003cSKyle Evans static const char * __unused
new_symlink(size_t __len)52020d003cSKyle Evans new_symlink(size_t __len)
53020d003cSKyle Evans {
54020d003cSKyle Evans 	static const char linkname[] = "link";
55020d003cSKyle Evans 	char target[MAXNAMLEN];
56020d003cSKyle Evans 	int error;
57020d003cSKyle Evans 
58020d003cSKyle Evans 	ATF_REQUIRE(__len <= sizeof(target));
59020d003cSKyle Evans 
60020d003cSKyle Evans 	arc4random_buf(target, sizeof(target));
61020d003cSKyle Evans 
62020d003cSKyle Evans 	error = unlink(linkname);
63020d003cSKyle Evans 	ATF_REQUIRE(error == 0 || errno == ENOENT);
64020d003cSKyle Evans 
65020d003cSKyle Evans 	error = symlink(target, linkname);
66020d003cSKyle Evans 	ATF_REQUIRE(error == 0);
67020d003cSKyle Evans 
68020d003cSKyle Evans 	return (linkname);
69020d003cSKyle Evans }
70020d003cSKyle Evans 
71020d003cSKyle 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 /*
116020d003cSKyle Evans  * Constructs a tmpfile that we can use for testing read(2) and friends.
117020d003cSKyle Evans  */
118020d003cSKyle Evans static int __unused
new_tmpfile(void)119020d003cSKyle Evans new_tmpfile(void)
120020d003cSKyle Evans {
121020d003cSKyle Evans 	char buf[1024];
122020d003cSKyle Evans 	ssize_t rv;
123020d003cSKyle Evans 	size_t written;
124020d003cSKyle Evans 	int fd;
125020d003cSKyle Evans 
126020d003cSKyle Evans 	fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
127020d003cSKyle Evans 	ATF_REQUIRE(fd >= 0);
128020d003cSKyle Evans 
129020d003cSKyle Evans 	written = 0;
130020d003cSKyle Evans 	while (written < TMPFILE_SIZE) {
131020d003cSKyle Evans 		rv = write(fd, buf, sizeof(buf));
132020d003cSKyle Evans 		ATF_REQUIRE(rv > 0);
133020d003cSKyle Evans 
134020d003cSKyle Evans 		written += rv;
135020d003cSKyle Evans 	}
136020d003cSKyle Evans 
137020d003cSKyle Evans 	ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
138020d003cSKyle Evans 	return (fd);
139020d003cSKyle Evans }
140020d003cSKyle Evans 
141020d003cSKyle Evans static void
disable_coredumps(void)142020d003cSKyle Evans disable_coredumps(void)
143020d003cSKyle Evans {
144020d003cSKyle Evans 	struct rlimit rl = { 0 };
145020d003cSKyle Evans 
146020d003cSKyle Evans 	if (setrlimit(RLIMIT_CORE, &rl) == -1)
147020d003cSKyle Evans 		_exit(EX_OSERR);
148020d003cSKyle Evans }
149020d003cSKyle Evans 
150cf8e5289SKyle Evans /*
151cf8e5289SKyle Evans  * Replaces stdin with a file that we can actually read from, for tests where
152cf8e5289SKyle Evans  * we want a FILE * or fd that we can get data from.
153cf8e5289SKyle Evans  */
154cf8e5289SKyle Evans static void __unused
replace_stdin(void)155cf8e5289SKyle Evans replace_stdin(void)
156cf8e5289SKyle Evans {
157cf8e5289SKyle Evans 	int fd;
158cf8e5289SKyle Evans 
159cf8e5289SKyle Evans 	fd = new_tmpfile();
160cf8e5289SKyle Evans 
161cf8e5289SKyle Evans 	(void)dup2(fd, STDIN_FILENO);
162cf8e5289SKyle Evans 	if (fd != STDIN_FILENO)
163cf8e5289SKyle Evans 		close(fd);
164cf8e5289SKyle Evans }
165cf8e5289SKyle Evans 
16609cdbf04SKyle Evans ATF_TC(bcopy_before_end);
ATF_TC_HEAD(bcopy_before_end,tc)16709cdbf04SKyle Evans ATF_TC_HEAD(bcopy_before_end, tc)
16809cdbf04SKyle Evans {
16909cdbf04SKyle Evans }
ATF_TC_BODY(bcopy_before_end,tc)170020d003cSKyle Evans ATF_TC_BODY(bcopy_before_end, tc)
171020d003cSKyle Evans {
172020d003cSKyle Evans #define BUF &__stack.__buf
173020d003cSKyle Evans 	struct {
174020d003cSKyle Evans 		uint8_t padding_l;
175020d003cSKyle Evans 		unsigned char __buf[42];
176020d003cSKyle Evans 		uint8_t padding_r;
177020d003cSKyle Evans 	} __stack;
178020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
179020d003cSKyle Evans 	const size_t __len = 42 - 1;
180020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
181020d003cSKyle Evans 	char src[__len + 10];
182020d003cSKyle Evans 
183020d003cSKyle Evans 	bcopy(src, __stack.__buf, __len);
184020d003cSKyle Evans #undef BUF
185020d003cSKyle Evans 
186020d003cSKyle Evans }
187020d003cSKyle Evans 
18809cdbf04SKyle Evans ATF_TC(bcopy_end);
ATF_TC_HEAD(bcopy_end,tc)18909cdbf04SKyle Evans ATF_TC_HEAD(bcopy_end, tc)
19009cdbf04SKyle Evans {
19109cdbf04SKyle Evans }
ATF_TC_BODY(bcopy_end,tc)192020d003cSKyle Evans ATF_TC_BODY(bcopy_end, tc)
193020d003cSKyle Evans {
194020d003cSKyle Evans #define BUF &__stack.__buf
195020d003cSKyle Evans 	struct {
196020d003cSKyle Evans 		uint8_t padding_l;
197020d003cSKyle Evans 		unsigned char __buf[42];
198020d003cSKyle Evans 		uint8_t padding_r;
199020d003cSKyle Evans 	} __stack;
200020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
201020d003cSKyle Evans 	const size_t __len = 42;
202020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
203020d003cSKyle Evans 	char src[__len + 10];
204020d003cSKyle Evans 
205020d003cSKyle Evans 	bcopy(src, __stack.__buf, __len);
206020d003cSKyle Evans #undef BUF
207020d003cSKyle Evans 
208020d003cSKyle Evans }
209020d003cSKyle Evans 
21009cdbf04SKyle Evans ATF_TC(bcopy_heap_before_end);
ATF_TC_HEAD(bcopy_heap_before_end,tc)21109cdbf04SKyle Evans ATF_TC_HEAD(bcopy_heap_before_end, tc)
21209cdbf04SKyle Evans {
21309cdbf04SKyle Evans }
ATF_TC_BODY(bcopy_heap_before_end,tc)214020d003cSKyle Evans ATF_TC_BODY(bcopy_heap_before_end, tc)
215020d003cSKyle Evans {
216020d003cSKyle Evans #define BUF __stack.__buf
217020d003cSKyle Evans 	struct {
218020d003cSKyle Evans 		uint8_t padding_l;
219020d003cSKyle Evans 		unsigned char * __buf;
220020d003cSKyle Evans 		uint8_t padding_r;
221020d003cSKyle Evans 	} __stack;
222020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
223020d003cSKyle Evans 	const size_t __len = 42 - 1;
224020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
225020d003cSKyle Evans 	char src[__len + 10];
226020d003cSKyle Evans 
227020d003cSKyle Evans 	__stack.__buf = malloc(__bufsz);
228020d003cSKyle Evans 
229020d003cSKyle Evans 	bcopy(src, __stack.__buf, __len);
230020d003cSKyle Evans #undef BUF
231020d003cSKyle Evans 
232020d003cSKyle Evans }
233020d003cSKyle Evans 
23409cdbf04SKyle Evans ATF_TC(bcopy_heap_end);
ATF_TC_HEAD(bcopy_heap_end,tc)23509cdbf04SKyle Evans ATF_TC_HEAD(bcopy_heap_end, tc)
23609cdbf04SKyle Evans {
23709cdbf04SKyle Evans }
ATF_TC_BODY(bcopy_heap_end,tc)238020d003cSKyle Evans ATF_TC_BODY(bcopy_heap_end, tc)
239020d003cSKyle Evans {
240020d003cSKyle Evans #define BUF __stack.__buf
241020d003cSKyle Evans 	struct {
242020d003cSKyle Evans 		uint8_t padding_l;
243020d003cSKyle Evans 		unsigned char * __buf;
244020d003cSKyle Evans 		uint8_t padding_r;
245020d003cSKyle Evans 	} __stack;
246020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
247020d003cSKyle Evans 	const size_t __len = 42;
248020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
249020d003cSKyle Evans 	char src[__len + 10];
250020d003cSKyle Evans 
251020d003cSKyle Evans 	__stack.__buf = malloc(__bufsz);
252020d003cSKyle Evans 
253020d003cSKyle Evans 	bcopy(src, __stack.__buf, __len);
254020d003cSKyle Evans #undef BUF
255020d003cSKyle Evans 
256020d003cSKyle Evans }
257020d003cSKyle Evans 
25809cdbf04SKyle Evans ATF_TC(bcopy_heap_after_end);
ATF_TC_HEAD(bcopy_heap_after_end,tc)25909cdbf04SKyle Evans ATF_TC_HEAD(bcopy_heap_after_end, tc)
26009cdbf04SKyle Evans {
26109cdbf04SKyle Evans }
ATF_TC_BODY(bcopy_heap_after_end,tc)262020d003cSKyle Evans ATF_TC_BODY(bcopy_heap_after_end, tc)
263020d003cSKyle Evans {
264020d003cSKyle Evans #define BUF __stack.__buf
265020d003cSKyle Evans 	struct {
266020d003cSKyle Evans 		uint8_t padding_l;
267020d003cSKyle Evans 		unsigned char * __buf;
268020d003cSKyle Evans 		uint8_t padding_r;
269020d003cSKyle Evans 	} __stack;
270020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
271020d003cSKyle Evans 	const size_t __len = 42 + 1;
272020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
273020d003cSKyle Evans 	pid_t __child;
274020d003cSKyle Evans 	int __status;
275020d003cSKyle Evans 	char src[__len + 10];
276020d003cSKyle Evans 
277020d003cSKyle Evans 	__child = fork();
278020d003cSKyle Evans 	ATF_REQUIRE(__child >= 0);
279020d003cSKyle Evans 	if (__child > 0)
280020d003cSKyle Evans 		goto monitor;
281020d003cSKyle Evans 
282020d003cSKyle Evans 	/* Child */
283020d003cSKyle Evans 	disable_coredumps();
284020d003cSKyle Evans 	__stack.__buf = malloc(__bufsz);
285020d003cSKyle Evans 
286020d003cSKyle Evans 	bcopy(src, __stack.__buf, __len);
287020d003cSKyle Evans 	_exit(EX_SOFTWARE);	/* Should have aborted. */
288020d003cSKyle Evans 
289020d003cSKyle Evans monitor:
290020d003cSKyle Evans 	while (waitpid(__child, &__status, 0) != __child) {
291020d003cSKyle Evans 		ATF_REQUIRE_EQ(EINTR, errno);
292020d003cSKyle Evans 	}
293020d003cSKyle Evans 
294020d003cSKyle Evans 	if (!WIFSIGNALED(__status)) {
295020d003cSKyle Evans 		switch (WEXITSTATUS(__status)) {
296020d003cSKyle Evans 		case EX_SOFTWARE:
297020d003cSKyle Evans 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
298020d003cSKyle Evans 			break;
299020d003cSKyle Evans 		case EX_OSERR:
300020d003cSKyle Evans 			atf_tc_fail("setrlimit(2) failed");
301020d003cSKyle Evans 			break;
302020d003cSKyle Evans 		default:
303020d003cSKyle Evans 			atf_tc_fail("child exited with status %d",
304020d003cSKyle Evans 			    WEXITSTATUS(__status));
305020d003cSKyle Evans 		}
306020d003cSKyle Evans 	} else {
307020d003cSKyle Evans 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
308020d003cSKyle Evans 	}
309020d003cSKyle Evans #undef BUF
310020d003cSKyle Evans 
311020d003cSKyle Evans }
312020d003cSKyle Evans 
31309cdbf04SKyle Evans ATF_TC(bzero_before_end);
ATF_TC_HEAD(bzero_before_end,tc)31409cdbf04SKyle Evans ATF_TC_HEAD(bzero_before_end, tc)
31509cdbf04SKyle Evans {
31609cdbf04SKyle Evans }
ATF_TC_BODY(bzero_before_end,tc)317020d003cSKyle Evans ATF_TC_BODY(bzero_before_end, tc)
318020d003cSKyle Evans {
319020d003cSKyle Evans #define BUF &__stack.__buf
320020d003cSKyle Evans 	struct {
321020d003cSKyle Evans 		uint8_t padding_l;
322020d003cSKyle Evans 		unsigned char __buf[42];
323020d003cSKyle Evans 		uint8_t padding_r;
324020d003cSKyle Evans 	} __stack;
325020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
326020d003cSKyle Evans 	const size_t __len = 42 - 1;
327020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
328020d003cSKyle Evans 
329020d003cSKyle Evans 	bzero(__stack.__buf, __len);
330020d003cSKyle Evans #undef BUF
331020d003cSKyle Evans 
332020d003cSKyle Evans }
333020d003cSKyle Evans 
33409cdbf04SKyle Evans ATF_TC(bzero_end);
ATF_TC_HEAD(bzero_end,tc)33509cdbf04SKyle Evans ATF_TC_HEAD(bzero_end, tc)
33609cdbf04SKyle Evans {
33709cdbf04SKyle Evans }
ATF_TC_BODY(bzero_end,tc)338020d003cSKyle Evans ATF_TC_BODY(bzero_end, tc)
339020d003cSKyle Evans {
340020d003cSKyle Evans #define BUF &__stack.__buf
341020d003cSKyle Evans 	struct {
342020d003cSKyle Evans 		uint8_t padding_l;
343020d003cSKyle Evans 		unsigned char __buf[42];
344020d003cSKyle Evans 		uint8_t padding_r;
345020d003cSKyle Evans 	} __stack;
346020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
347020d003cSKyle Evans 	const size_t __len = 42;
348020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
349020d003cSKyle Evans 
350020d003cSKyle Evans 	bzero(__stack.__buf, __len);
351020d003cSKyle Evans #undef BUF
352020d003cSKyle Evans 
353020d003cSKyle Evans }
354020d003cSKyle Evans 
35509cdbf04SKyle Evans ATF_TC(bzero_heap_before_end);
ATF_TC_HEAD(bzero_heap_before_end,tc)35609cdbf04SKyle Evans ATF_TC_HEAD(bzero_heap_before_end, tc)
35709cdbf04SKyle Evans {
35809cdbf04SKyle Evans }
ATF_TC_BODY(bzero_heap_before_end,tc)359020d003cSKyle Evans ATF_TC_BODY(bzero_heap_before_end, tc)
360020d003cSKyle Evans {
361020d003cSKyle Evans #define BUF __stack.__buf
362020d003cSKyle Evans 	struct {
363020d003cSKyle Evans 		uint8_t padding_l;
364020d003cSKyle Evans 		unsigned char * __buf;
365020d003cSKyle Evans 		uint8_t padding_r;
366020d003cSKyle Evans 	} __stack;
367020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
368020d003cSKyle Evans 	const size_t __len = 42 - 1;
369020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
370020d003cSKyle Evans 
371020d003cSKyle Evans 	__stack.__buf = malloc(__bufsz);
372020d003cSKyle Evans 
373020d003cSKyle Evans 	bzero(__stack.__buf, __len);
374020d003cSKyle Evans #undef BUF
375020d003cSKyle Evans 
376020d003cSKyle Evans }
377020d003cSKyle Evans 
37809cdbf04SKyle Evans ATF_TC(bzero_heap_end);
ATF_TC_HEAD(bzero_heap_end,tc)37909cdbf04SKyle Evans ATF_TC_HEAD(bzero_heap_end, tc)
38009cdbf04SKyle Evans {
38109cdbf04SKyle Evans }
ATF_TC_BODY(bzero_heap_end,tc)382020d003cSKyle Evans ATF_TC_BODY(bzero_heap_end, tc)
383020d003cSKyle Evans {
384020d003cSKyle Evans #define BUF __stack.__buf
385020d003cSKyle Evans 	struct {
386020d003cSKyle Evans 		uint8_t padding_l;
387020d003cSKyle Evans 		unsigned char * __buf;
388020d003cSKyle Evans 		uint8_t padding_r;
389020d003cSKyle Evans 	} __stack;
390020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
391020d003cSKyle Evans 	const size_t __len = 42;
392020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
393020d003cSKyle Evans 
394020d003cSKyle Evans 	__stack.__buf = malloc(__bufsz);
395020d003cSKyle Evans 
396020d003cSKyle Evans 	bzero(__stack.__buf, __len);
397020d003cSKyle Evans #undef BUF
398020d003cSKyle Evans 
399020d003cSKyle Evans }
400020d003cSKyle Evans 
40109cdbf04SKyle Evans ATF_TC(bzero_heap_after_end);
ATF_TC_HEAD(bzero_heap_after_end,tc)40209cdbf04SKyle Evans ATF_TC_HEAD(bzero_heap_after_end, tc)
40309cdbf04SKyle Evans {
40409cdbf04SKyle Evans }
ATF_TC_BODY(bzero_heap_after_end,tc)405020d003cSKyle Evans ATF_TC_BODY(bzero_heap_after_end, tc)
406020d003cSKyle Evans {
407020d003cSKyle Evans #define BUF __stack.__buf
408020d003cSKyle Evans 	struct {
409020d003cSKyle Evans 		uint8_t padding_l;
410020d003cSKyle Evans 		unsigned char * __buf;
411020d003cSKyle Evans 		uint8_t padding_r;
412020d003cSKyle Evans 	} __stack;
413020d003cSKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
414020d003cSKyle Evans 	const size_t __len = 42 + 1;
415020d003cSKyle Evans 	const size_t __idx __unused = __len - 1;
416020d003cSKyle Evans 	pid_t __child;
417020d003cSKyle Evans 	int __status;
418020d003cSKyle Evans 
419020d003cSKyle Evans 	__child = fork();
420020d003cSKyle Evans 	ATF_REQUIRE(__child >= 0);
421020d003cSKyle Evans 	if (__child > 0)
422020d003cSKyle Evans 		goto monitor;
423020d003cSKyle Evans 
424020d003cSKyle Evans 	/* Child */
425020d003cSKyle Evans 	disable_coredumps();
426020d003cSKyle Evans 	__stack.__buf = malloc(__bufsz);
427020d003cSKyle Evans 
428020d003cSKyle Evans 	bzero(__stack.__buf, __len);
429020d003cSKyle Evans 	_exit(EX_SOFTWARE);	/* Should have aborted. */
430020d003cSKyle Evans 
431020d003cSKyle Evans monitor:
432020d003cSKyle Evans 	while (waitpid(__child, &__status, 0) != __child) {
433020d003cSKyle Evans 		ATF_REQUIRE_EQ(EINTR, errno);
434020d003cSKyle Evans 	}
435020d003cSKyle Evans 
436020d003cSKyle Evans 	if (!WIFSIGNALED(__status)) {
437020d003cSKyle Evans 		switch (WEXITSTATUS(__status)) {
438020d003cSKyle Evans 		case EX_SOFTWARE:
439020d003cSKyle Evans 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
440020d003cSKyle Evans 			break;
441020d003cSKyle Evans 		case EX_OSERR:
442020d003cSKyle Evans 			atf_tc_fail("setrlimit(2) failed");
443020d003cSKyle Evans 			break;
444020d003cSKyle Evans 		default:
445020d003cSKyle Evans 			atf_tc_fail("child exited with status %d",
446020d003cSKyle Evans 			    WEXITSTATUS(__status));
447020d003cSKyle Evans 		}
448020d003cSKyle Evans 	} else {
449020d003cSKyle Evans 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
450020d003cSKyle Evans 	}
451020d003cSKyle Evans #undef BUF
452020d003cSKyle Evans 
453020d003cSKyle Evans }
454020d003cSKyle Evans 
45509cdbf04SKyle Evans ATF_TC(explicit_bzero_before_end);
ATF_TC_HEAD(explicit_bzero_before_end,tc)45609cdbf04SKyle Evans ATF_TC_HEAD(explicit_bzero_before_end, tc)
45709cdbf04SKyle Evans {
45809cdbf04SKyle Evans }
ATF_TC_BODY(explicit_bzero_before_end,tc)459cf8e5289SKyle Evans ATF_TC_BODY(explicit_bzero_before_end, tc)
460cf8e5289SKyle Evans {
461cf8e5289SKyle Evans #define BUF &__stack.__buf
462cf8e5289SKyle Evans 	struct {
463cf8e5289SKyle Evans 		uint8_t padding_l;
464cf8e5289SKyle Evans 		unsigned char __buf[42];
465cf8e5289SKyle Evans 		uint8_t padding_r;
466cf8e5289SKyle Evans 	} __stack;
467cf8e5289SKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
468cf8e5289SKyle Evans 	const size_t __len = 42 - 1;
469cf8e5289SKyle Evans 	const size_t __idx __unused = __len - 1;
470cf8e5289SKyle Evans 
471cf8e5289SKyle Evans 	explicit_bzero(__stack.__buf, __len);
472cf8e5289SKyle Evans #undef BUF
473cf8e5289SKyle Evans 
474cf8e5289SKyle Evans }
475cf8e5289SKyle Evans 
47609cdbf04SKyle Evans ATF_TC(explicit_bzero_end);
ATF_TC_HEAD(explicit_bzero_end,tc)47709cdbf04SKyle Evans ATF_TC_HEAD(explicit_bzero_end, tc)
47809cdbf04SKyle Evans {
47909cdbf04SKyle Evans }
ATF_TC_BODY(explicit_bzero_end,tc)480cf8e5289SKyle Evans ATF_TC_BODY(explicit_bzero_end, tc)
481cf8e5289SKyle Evans {
482cf8e5289SKyle Evans #define BUF &__stack.__buf
483cf8e5289SKyle Evans 	struct {
484cf8e5289SKyle Evans 		uint8_t padding_l;
485cf8e5289SKyle Evans 		unsigned char __buf[42];
486cf8e5289SKyle Evans 		uint8_t padding_r;
487cf8e5289SKyle Evans 	} __stack;
488cf8e5289SKyle Evans 	const size_t __bufsz __unused = sizeof(__stack.__buf);
489cf8e5289SKyle Evans 	const size_t __len = 42;
490cf8e5289SKyle Evans 	const size_t __idx __unused = __len - 1;
491cf8e5289SKyle Evans 
492cf8e5289SKyle Evans 	explicit_bzero(__stack.__buf, __len);
493cf8e5289SKyle Evans #undef BUF
494cf8e5289SKyle Evans 
495cf8e5289SKyle Evans }
496cf8e5289SKyle Evans 
49709cdbf04SKyle Evans ATF_TC(explicit_bzero_heap_before_end);
ATF_TC_HEAD(explicit_bzero_heap_before_end,tc)49809cdbf04SKyle Evans ATF_TC_HEAD(explicit_bzero_heap_before_end, tc)
49909cdbf04SKyle Evans {
50009cdbf04SKyle Evans }
ATF_TC_BODY(explicit_bzero_heap_before_end,tc)501cf8e5289SKyle Evans ATF_TC_BODY(explicit_bzero_heap_before_end, tc)
502cf8e5289SKyle Evans {
503cf8e5289SKyle Evans #define BUF __stack.__buf
504cf8e5289SKyle Evans 	struct {
505cf8e5289SKyle Evans 		uint8_t padding_l;
506cf8e5289SKyle Evans 		unsigned char * __buf;
507cf8e5289SKyle Evans 		uint8_t padding_r;
508cf8e5289SKyle Evans 	} __stack;
509cf8e5289SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
510cf8e5289SKyle Evans 	const size_t __len = 42 - 1;
511cf8e5289SKyle Evans 	const size_t __idx __unused = __len - 1;
512cf8e5289SKyle Evans 
513cf8e5289SKyle Evans 	__stack.__buf = malloc(__bufsz);
514cf8e5289SKyle Evans 
515cf8e5289SKyle Evans 	explicit_bzero(__stack.__buf, __len);
516cf8e5289SKyle Evans #undef BUF
517cf8e5289SKyle Evans 
518cf8e5289SKyle Evans }
519cf8e5289SKyle Evans 
52009cdbf04SKyle Evans ATF_TC(explicit_bzero_heap_end);
ATF_TC_HEAD(explicit_bzero_heap_end,tc)52109cdbf04SKyle Evans ATF_TC_HEAD(explicit_bzero_heap_end, tc)
52209cdbf04SKyle Evans {
52309cdbf04SKyle Evans }
ATF_TC_BODY(explicit_bzero_heap_end,tc)524cf8e5289SKyle Evans ATF_TC_BODY(explicit_bzero_heap_end, tc)
525cf8e5289SKyle Evans {
526cf8e5289SKyle Evans #define BUF __stack.__buf
527cf8e5289SKyle Evans 	struct {
528cf8e5289SKyle Evans 		uint8_t padding_l;
529cf8e5289SKyle Evans 		unsigned char * __buf;
530cf8e5289SKyle Evans 		uint8_t padding_r;
531cf8e5289SKyle Evans 	} __stack;
532cf8e5289SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
533cf8e5289SKyle Evans 	const size_t __len = 42;
534cf8e5289SKyle Evans 	const size_t __idx __unused = __len - 1;
535cf8e5289SKyle Evans 
536cf8e5289SKyle Evans 	__stack.__buf = malloc(__bufsz);
537cf8e5289SKyle Evans 
538cf8e5289SKyle Evans 	explicit_bzero(__stack.__buf, __len);
539cf8e5289SKyle Evans #undef BUF
540cf8e5289SKyle Evans 
541cf8e5289SKyle Evans }
542cf8e5289SKyle Evans 
54309cdbf04SKyle Evans ATF_TC(explicit_bzero_heap_after_end);
ATF_TC_HEAD(explicit_bzero_heap_after_end,tc)54409cdbf04SKyle Evans ATF_TC_HEAD(explicit_bzero_heap_after_end, tc)
54509cdbf04SKyle Evans {
54609cdbf04SKyle Evans }
ATF_TC_BODY(explicit_bzero_heap_after_end,tc)547cf8e5289SKyle Evans ATF_TC_BODY(explicit_bzero_heap_after_end, tc)
548cf8e5289SKyle Evans {
549cf8e5289SKyle Evans #define BUF __stack.__buf
550cf8e5289SKyle Evans 	struct {
551cf8e5289SKyle Evans 		uint8_t padding_l;
552cf8e5289SKyle Evans 		unsigned char * __buf;
553cf8e5289SKyle Evans 		uint8_t padding_r;
554cf8e5289SKyle Evans 	} __stack;
555cf8e5289SKyle Evans 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
556cf8e5289SKyle Evans 	const size_t __len = 42 + 1;
557cf8e5289SKyle Evans 	const size_t __idx __unused = __len - 1;
558cf8e5289SKyle Evans 	pid_t __child;
559cf8e5289SKyle Evans 	int __status;
560cf8e5289SKyle Evans 
561cf8e5289SKyle Evans 	__child = fork();
562cf8e5289SKyle Evans 	ATF_REQUIRE(__child >= 0);
563cf8e5289SKyle Evans 	if (__child > 0)
564cf8e5289SKyle Evans 		goto monitor;
565cf8e5289SKyle Evans 
566cf8e5289SKyle Evans 	/* Child */
567cf8e5289SKyle Evans 	disable_coredumps();
568cf8e5289SKyle Evans 	__stack.__buf = malloc(__bufsz);
569cf8e5289SKyle Evans 
570cf8e5289SKyle Evans 	explicit_bzero(__stack.__buf, __len);
571cf8e5289SKyle Evans 	_exit(EX_SOFTWARE);	/* Should have aborted. */
572cf8e5289SKyle Evans 
573cf8e5289SKyle Evans monitor:
574cf8e5289SKyle Evans 	while (waitpid(__child, &__status, 0) != __child) {
575cf8e5289SKyle Evans 		ATF_REQUIRE_EQ(EINTR, errno);
576cf8e5289SKyle Evans 	}
577cf8e5289SKyle Evans 
578cf8e5289SKyle Evans 	if (!WIFSIGNALED(__status)) {
579cf8e5289SKyle Evans 		switch (WEXITSTATUS(__status)) {
580cf8e5289SKyle Evans 		case EX_SOFTWARE:
581cf8e5289SKyle Evans 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
582cf8e5289SKyle Evans 			break;
583cf8e5289SKyle Evans 		case EX_OSERR:
584cf8e5289SKyle Evans 			atf_tc_fail("setrlimit(2) failed");
585cf8e5289SKyle Evans 			break;
586cf8e5289SKyle Evans 		default:
587cf8e5289SKyle Evans 			atf_tc_fail("child exited with status %d",
588cf8e5289SKyle Evans 			    WEXITSTATUS(__status));
589cf8e5289SKyle Evans 		}
590cf8e5289SKyle Evans 	} else {
591cf8e5289SKyle Evans 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
592cf8e5289SKyle Evans 	}
593cf8e5289SKyle Evans #undef BUF
594cf8e5289SKyle Evans 
595cf8e5289SKyle Evans }
596cf8e5289SKyle Evans 
ATF_TP_ADD_TCS(tp)597020d003cSKyle Evans ATF_TP_ADD_TCS(tp)
598020d003cSKyle Evans {
599020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bcopy_before_end);
600020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bcopy_end);
601020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bcopy_heap_before_end);
602020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bcopy_heap_end);
603020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bcopy_heap_after_end);
604020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bzero_before_end);
605020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bzero_end);
606020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bzero_heap_before_end);
607020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bzero_heap_end);
608020d003cSKyle Evans 	ATF_TP_ADD_TC(tp, bzero_heap_after_end);
609cf8e5289SKyle Evans 	ATF_TP_ADD_TC(tp, explicit_bzero_before_end);
610cf8e5289SKyle Evans 	ATF_TP_ADD_TC(tp, explicit_bzero_end);
611cf8e5289SKyle Evans 	ATF_TP_ADD_TC(tp, explicit_bzero_heap_before_end);
612cf8e5289SKyle Evans 	ATF_TP_ADD_TC(tp, explicit_bzero_heap_end);
613cf8e5289SKyle Evans 	ATF_TP_ADD_TC(tp, explicit_bzero_heap_after_end);
614020d003cSKyle Evans 	return (atf_no_error());
615020d003cSKyle Evans }
616