xref: /freebsd/lib/libc/tests/secure/fortify_strings_test.c (revision c10d567ea022de8705fb23f8563c4726f2d09ca0)
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/resource.h>
8 #include <sys/time.h>
9 #include <sys/wait.h>
10 #include <dirent.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <limits.h>
14 #include <signal.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <strings.h>
19 #include <sysexits.h>
20 #include <unistd.h>
21 #include <atf-c.h>
22 
23 /*
24  * Create a new symlink to use for readlink(2) style tests, we'll just use a
25  * random target name to have something interesting to look at.
26  */
27 static const char * __unused
28 new_symlink(size_t __len)
29 {
30 	static const char linkname[] = "link";
31 	char target[MAXNAMLEN];
32 	int error;
33 
34 	ATF_REQUIRE(__len <= sizeof(target));
35 
36 	arc4random_buf(target, sizeof(target));
37 
38 	error = unlink(linkname);
39 	ATF_REQUIRE(error == 0 || errno == ENOENT);
40 
41 	error = symlink(target, linkname);
42 	ATF_REQUIRE(error == 0);
43 
44 	return (linkname);
45 }
46 
47 /*
48  * Constructs a tmpfile that we can use for testing read(2) and friends.
49  */
50 static int __unused
51 new_tmpfile(void)
52 {
53 	char buf[1024];
54 	ssize_t rv;
55 	size_t written;
56 	int fd;
57 
58 	fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
59 	ATF_REQUIRE(fd >= 0);
60 
61 	written = 0;
62 	while (written < TMPFILE_SIZE) {
63 		rv = write(fd, buf, sizeof(buf));
64 		ATF_REQUIRE(rv > 0);
65 
66 		written += rv;
67 	}
68 
69 	ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
70 	return (fd);
71 }
72 
73 static void
74 disable_coredumps(void)
75 {
76 	struct rlimit rl = { 0 };
77 
78 	if (setrlimit(RLIMIT_CORE, &rl) == -1)
79 		_exit(EX_OSERR);
80 }
81 
82 ATF_TC_WITHOUT_HEAD(bcopy_before_end);
83 ATF_TC_BODY(bcopy_before_end, tc)
84 {
85 #define BUF &__stack.__buf
86 	struct {
87 		uint8_t padding_l;
88 		unsigned char __buf[42];
89 		uint8_t padding_r;
90 	} __stack;
91 	const size_t __bufsz __unused = sizeof(__stack.__buf);
92 	const size_t __len = 42 - 1;
93 	const size_t __idx __unused = __len - 1;
94 	char src[__len + 10];
95 
96 	bcopy(src, __stack.__buf, __len);
97 #undef BUF
98 
99 }
100 
101 ATF_TC_WITHOUT_HEAD(bcopy_end);
102 ATF_TC_BODY(bcopy_end, tc)
103 {
104 #define BUF &__stack.__buf
105 	struct {
106 		uint8_t padding_l;
107 		unsigned char __buf[42];
108 		uint8_t padding_r;
109 	} __stack;
110 	const size_t __bufsz __unused = sizeof(__stack.__buf);
111 	const size_t __len = 42;
112 	const size_t __idx __unused = __len - 1;
113 	char src[__len + 10];
114 
115 	bcopy(src, __stack.__buf, __len);
116 #undef BUF
117 
118 }
119 
120 ATF_TC_WITHOUT_HEAD(bcopy_heap_before_end);
121 ATF_TC_BODY(bcopy_heap_before_end, tc)
122 {
123 #define BUF __stack.__buf
124 	struct {
125 		uint8_t padding_l;
126 		unsigned char * __buf;
127 		uint8_t padding_r;
128 	} __stack;
129 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
130 	const size_t __len = 42 - 1;
131 	const size_t __idx __unused = __len - 1;
132 	char src[__len + 10];
133 
134 	__stack.__buf = malloc(__bufsz);
135 
136 	bcopy(src, __stack.__buf, __len);
137 #undef BUF
138 
139 }
140 
141 ATF_TC_WITHOUT_HEAD(bcopy_heap_end);
142 ATF_TC_BODY(bcopy_heap_end, tc)
143 {
144 #define BUF __stack.__buf
145 	struct {
146 		uint8_t padding_l;
147 		unsigned char * __buf;
148 		uint8_t padding_r;
149 	} __stack;
150 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
151 	const size_t __len = 42;
152 	const size_t __idx __unused = __len - 1;
153 	char src[__len + 10];
154 
155 	__stack.__buf = malloc(__bufsz);
156 
157 	bcopy(src, __stack.__buf, __len);
158 #undef BUF
159 
160 }
161 
162 ATF_TC_WITHOUT_HEAD(bcopy_heap_after_end);
163 ATF_TC_BODY(bcopy_heap_after_end, tc)
164 {
165 #define BUF __stack.__buf
166 	struct {
167 		uint8_t padding_l;
168 		unsigned char * __buf;
169 		uint8_t padding_r;
170 	} __stack;
171 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
172 	const size_t __len = 42 + 1;
173 	const size_t __idx __unused = __len - 1;
174 	pid_t __child;
175 	int __status;
176 	char src[__len + 10];
177 
178 	__child = fork();
179 	ATF_REQUIRE(__child >= 0);
180 	if (__child > 0)
181 		goto monitor;
182 
183 	/* Child */
184 	disable_coredumps();
185 	__stack.__buf = malloc(__bufsz);
186 
187 	bcopy(src, __stack.__buf, __len);
188 	_exit(EX_SOFTWARE);	/* Should have aborted. */
189 
190 monitor:
191 	while (waitpid(__child, &__status, 0) != __child) {
192 		ATF_REQUIRE_EQ(EINTR, errno);
193 	}
194 
195 	if (!WIFSIGNALED(__status)) {
196 		switch (WEXITSTATUS(__status)) {
197 		case EX_SOFTWARE:
198 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
199 			break;
200 		case EX_OSERR:
201 			atf_tc_fail("setrlimit(2) failed");
202 			break;
203 		default:
204 			atf_tc_fail("child exited with status %d",
205 			    WEXITSTATUS(__status));
206 		}
207 	} else {
208 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
209 	}
210 #undef BUF
211 
212 }
213 
214 ATF_TC_WITHOUT_HEAD(bzero_before_end);
215 ATF_TC_BODY(bzero_before_end, tc)
216 {
217 #define BUF &__stack.__buf
218 	struct {
219 		uint8_t padding_l;
220 		unsigned char __buf[42];
221 		uint8_t padding_r;
222 	} __stack;
223 	const size_t __bufsz __unused = sizeof(__stack.__buf);
224 	const size_t __len = 42 - 1;
225 	const size_t __idx __unused = __len - 1;
226 
227 	bzero(__stack.__buf, __len);
228 #undef BUF
229 
230 }
231 
232 ATF_TC_WITHOUT_HEAD(bzero_end);
233 ATF_TC_BODY(bzero_end, tc)
234 {
235 #define BUF &__stack.__buf
236 	struct {
237 		uint8_t padding_l;
238 		unsigned char __buf[42];
239 		uint8_t padding_r;
240 	} __stack;
241 	const size_t __bufsz __unused = sizeof(__stack.__buf);
242 	const size_t __len = 42;
243 	const size_t __idx __unused = __len - 1;
244 
245 	bzero(__stack.__buf, __len);
246 #undef BUF
247 
248 }
249 
250 ATF_TC_WITHOUT_HEAD(bzero_heap_before_end);
251 ATF_TC_BODY(bzero_heap_before_end, tc)
252 {
253 #define BUF __stack.__buf
254 	struct {
255 		uint8_t padding_l;
256 		unsigned char * __buf;
257 		uint8_t padding_r;
258 	} __stack;
259 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
260 	const size_t __len = 42 - 1;
261 	const size_t __idx __unused = __len - 1;
262 
263 	__stack.__buf = malloc(__bufsz);
264 
265 	bzero(__stack.__buf, __len);
266 #undef BUF
267 
268 }
269 
270 ATF_TC_WITHOUT_HEAD(bzero_heap_end);
271 ATF_TC_BODY(bzero_heap_end, tc)
272 {
273 #define BUF __stack.__buf
274 	struct {
275 		uint8_t padding_l;
276 		unsigned char * __buf;
277 		uint8_t padding_r;
278 	} __stack;
279 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
280 	const size_t __len = 42;
281 	const size_t __idx __unused = __len - 1;
282 
283 	__stack.__buf = malloc(__bufsz);
284 
285 	bzero(__stack.__buf, __len);
286 #undef BUF
287 
288 }
289 
290 ATF_TC_WITHOUT_HEAD(bzero_heap_after_end);
291 ATF_TC_BODY(bzero_heap_after_end, tc)
292 {
293 #define BUF __stack.__buf
294 	struct {
295 		uint8_t padding_l;
296 		unsigned char * __buf;
297 		uint8_t padding_r;
298 	} __stack;
299 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
300 	const size_t __len = 42 + 1;
301 	const size_t __idx __unused = __len - 1;
302 	pid_t __child;
303 	int __status;
304 
305 	__child = fork();
306 	ATF_REQUIRE(__child >= 0);
307 	if (__child > 0)
308 		goto monitor;
309 
310 	/* Child */
311 	disable_coredumps();
312 	__stack.__buf = malloc(__bufsz);
313 
314 	bzero(__stack.__buf, __len);
315 	_exit(EX_SOFTWARE);	/* Should have aborted. */
316 
317 monitor:
318 	while (waitpid(__child, &__status, 0) != __child) {
319 		ATF_REQUIRE_EQ(EINTR, errno);
320 	}
321 
322 	if (!WIFSIGNALED(__status)) {
323 		switch (WEXITSTATUS(__status)) {
324 		case EX_SOFTWARE:
325 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
326 			break;
327 		case EX_OSERR:
328 			atf_tc_fail("setrlimit(2) failed");
329 			break;
330 		default:
331 			atf_tc_fail("child exited with status %d",
332 			    WEXITSTATUS(__status));
333 		}
334 	} else {
335 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
336 	}
337 #undef BUF
338 
339 }
340 
341 ATF_TP_ADD_TCS(tp)
342 {
343 	ATF_TP_ADD_TC(tp, bcopy_before_end);
344 	ATF_TP_ADD_TC(tp, bcopy_end);
345 	ATF_TP_ADD_TC(tp, bcopy_heap_before_end);
346 	ATF_TP_ADD_TC(tp, bcopy_heap_end);
347 	ATF_TP_ADD_TC(tp, bcopy_heap_after_end);
348 	ATF_TP_ADD_TC(tp, bzero_before_end);
349 	ATF_TP_ADD_TC(tp, bzero_end);
350 	ATF_TP_ADD_TC(tp, bzero_heap_before_end);
351 	ATF_TP_ADD_TC(tp, bzero_heap_end);
352 	ATF_TP_ADD_TC(tp, bzero_heap_after_end);
353 	return (atf_no_error());
354 }
355