xref: /freebsd/lib/libc/tests/secure/fortify_strings_test.c (revision 1ace24b30cad59c8ae509d0c690aa55b8df73136)
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/random.h>
8 #include <sys/resource.h>
9 #include <sys/time.h>
10 #include <sys/uio.h>
11 #include <sys/wait.h>
12 #include <dirent.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <limits.h>
16 #include <poll.h>
17 #include <signal.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <strings.h>
22 #include <sysexits.h>
23 #include <unistd.h>
24 #include <wchar.h>
25 #include <atf-c.h>
26 
27 static FILE * __unused
28 new_fp(size_t __len)
29 {
30 	static char fpbuf[LINE_MAX];
31 	FILE *fp;
32 
33 	ATF_REQUIRE(__len <= sizeof(fpbuf));
34 
35 	memset(fpbuf, 'A', sizeof(fpbuf) - 1);
36 	fpbuf[sizeof(fpbuf) - 1] = '\0';
37 
38 	fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
39 	ATF_REQUIRE(fp != NULL);
40 
41 	return (fp);
42 }
43 
44 /*
45  * Create a new symlink to use for readlink(2) style tests, we'll just use a
46  * random target name to have something interesting to look at.
47  */
48 static const char * __unused
49 new_symlink(size_t __len)
50 {
51 	static const char linkname[] = "link";
52 	char target[MAXNAMLEN];
53 	int error;
54 
55 	ATF_REQUIRE(__len <= sizeof(target));
56 
57 	arc4random_buf(target, sizeof(target));
58 
59 	error = unlink(linkname);
60 	ATF_REQUIRE(error == 0 || errno == ENOENT);
61 
62 	error = symlink(target, linkname);
63 	ATF_REQUIRE(error == 0);
64 
65 	return (linkname);
66 }
67 
68 /*
69  * Constructs a tmpfile that we can use for testing read(2) and friends.
70  */
71 static int __unused
72 new_tmpfile(void)
73 {
74 	char buf[1024];
75 	ssize_t rv;
76 	size_t written;
77 	int fd;
78 
79 	fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
80 	ATF_REQUIRE(fd >= 0);
81 
82 	written = 0;
83 	while (written < TMPFILE_SIZE) {
84 		rv = write(fd, buf, sizeof(buf));
85 		ATF_REQUIRE(rv > 0);
86 
87 		written += rv;
88 	}
89 
90 	ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET));
91 	return (fd);
92 }
93 
94 static void
95 disable_coredumps(void)
96 {
97 	struct rlimit rl = { 0 };
98 
99 	if (setrlimit(RLIMIT_CORE, &rl) == -1)
100 		_exit(EX_OSERR);
101 }
102 
103 /*
104  * Replaces stdin with a file that we can actually read from, for tests where
105  * we want a FILE * or fd that we can get data from.
106  */
107 static void __unused
108 replace_stdin(void)
109 {
110 	int fd;
111 
112 	fd = new_tmpfile();
113 
114 	(void)dup2(fd, STDIN_FILENO);
115 	if (fd != STDIN_FILENO)
116 		close(fd);
117 }
118 
119 ATF_TC_WITHOUT_HEAD(bcopy_before_end);
120 ATF_TC_BODY(bcopy_before_end, tc)
121 {
122 #define BUF &__stack.__buf
123 	struct {
124 		uint8_t padding_l;
125 		unsigned char __buf[42];
126 		uint8_t padding_r;
127 	} __stack;
128 	const size_t __bufsz __unused = sizeof(__stack.__buf);
129 	const size_t __len = 42 - 1;
130 	const size_t __idx __unused = __len - 1;
131 	char src[__len + 10];
132 
133 	bcopy(src, __stack.__buf, __len);
134 #undef BUF
135 
136 }
137 
138 ATF_TC_WITHOUT_HEAD(bcopy_end);
139 ATF_TC_BODY(bcopy_end, tc)
140 {
141 #define BUF &__stack.__buf
142 	struct {
143 		uint8_t padding_l;
144 		unsigned char __buf[42];
145 		uint8_t padding_r;
146 	} __stack;
147 	const size_t __bufsz __unused = sizeof(__stack.__buf);
148 	const size_t __len = 42;
149 	const size_t __idx __unused = __len - 1;
150 	char src[__len + 10];
151 
152 	bcopy(src, __stack.__buf, __len);
153 #undef BUF
154 
155 }
156 
157 ATF_TC_WITHOUT_HEAD(bcopy_heap_before_end);
158 ATF_TC_BODY(bcopy_heap_before_end, tc)
159 {
160 #define BUF __stack.__buf
161 	struct {
162 		uint8_t padding_l;
163 		unsigned char * __buf;
164 		uint8_t padding_r;
165 	} __stack;
166 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
167 	const size_t __len = 42 - 1;
168 	const size_t __idx __unused = __len - 1;
169 	char src[__len + 10];
170 
171 	__stack.__buf = malloc(__bufsz);
172 
173 	bcopy(src, __stack.__buf, __len);
174 #undef BUF
175 
176 }
177 
178 ATF_TC_WITHOUT_HEAD(bcopy_heap_end);
179 ATF_TC_BODY(bcopy_heap_end, tc)
180 {
181 #define BUF __stack.__buf
182 	struct {
183 		uint8_t padding_l;
184 		unsigned char * __buf;
185 		uint8_t padding_r;
186 	} __stack;
187 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
188 	const size_t __len = 42;
189 	const size_t __idx __unused = __len - 1;
190 	char src[__len + 10];
191 
192 	__stack.__buf = malloc(__bufsz);
193 
194 	bcopy(src, __stack.__buf, __len);
195 #undef BUF
196 
197 }
198 
199 ATF_TC_WITHOUT_HEAD(bcopy_heap_after_end);
200 ATF_TC_BODY(bcopy_heap_after_end, tc)
201 {
202 #define BUF __stack.__buf
203 	struct {
204 		uint8_t padding_l;
205 		unsigned char * __buf;
206 		uint8_t padding_r;
207 	} __stack;
208 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
209 	const size_t __len = 42 + 1;
210 	const size_t __idx __unused = __len - 1;
211 	pid_t __child;
212 	int __status;
213 	char src[__len + 10];
214 
215 	__child = fork();
216 	ATF_REQUIRE(__child >= 0);
217 	if (__child > 0)
218 		goto monitor;
219 
220 	/* Child */
221 	disable_coredumps();
222 	__stack.__buf = malloc(__bufsz);
223 
224 	bcopy(src, __stack.__buf, __len);
225 	_exit(EX_SOFTWARE);	/* Should have aborted. */
226 
227 monitor:
228 	while (waitpid(__child, &__status, 0) != __child) {
229 		ATF_REQUIRE_EQ(EINTR, errno);
230 	}
231 
232 	if (!WIFSIGNALED(__status)) {
233 		switch (WEXITSTATUS(__status)) {
234 		case EX_SOFTWARE:
235 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
236 			break;
237 		case EX_OSERR:
238 			atf_tc_fail("setrlimit(2) failed");
239 			break;
240 		default:
241 			atf_tc_fail("child exited with status %d",
242 			    WEXITSTATUS(__status));
243 		}
244 	} else {
245 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
246 	}
247 #undef BUF
248 
249 }
250 
251 ATF_TC_WITHOUT_HEAD(bzero_before_end);
252 ATF_TC_BODY(bzero_before_end, tc)
253 {
254 #define BUF &__stack.__buf
255 	struct {
256 		uint8_t padding_l;
257 		unsigned char __buf[42];
258 		uint8_t padding_r;
259 	} __stack;
260 	const size_t __bufsz __unused = sizeof(__stack.__buf);
261 	const size_t __len = 42 - 1;
262 	const size_t __idx __unused = __len - 1;
263 
264 	bzero(__stack.__buf, __len);
265 #undef BUF
266 
267 }
268 
269 ATF_TC_WITHOUT_HEAD(bzero_end);
270 ATF_TC_BODY(bzero_end, tc)
271 {
272 #define BUF &__stack.__buf
273 	struct {
274 		uint8_t padding_l;
275 		unsigned char __buf[42];
276 		uint8_t padding_r;
277 	} __stack;
278 	const size_t __bufsz __unused = sizeof(__stack.__buf);
279 	const size_t __len = 42;
280 	const size_t __idx __unused = __len - 1;
281 
282 	bzero(__stack.__buf, __len);
283 #undef BUF
284 
285 }
286 
287 ATF_TC_WITHOUT_HEAD(bzero_heap_before_end);
288 ATF_TC_BODY(bzero_heap_before_end, tc)
289 {
290 #define BUF __stack.__buf
291 	struct {
292 		uint8_t padding_l;
293 		unsigned char * __buf;
294 		uint8_t padding_r;
295 	} __stack;
296 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
297 	const size_t __len = 42 - 1;
298 	const size_t __idx __unused = __len - 1;
299 
300 	__stack.__buf = malloc(__bufsz);
301 
302 	bzero(__stack.__buf, __len);
303 #undef BUF
304 
305 }
306 
307 ATF_TC_WITHOUT_HEAD(bzero_heap_end);
308 ATF_TC_BODY(bzero_heap_end, tc)
309 {
310 #define BUF __stack.__buf
311 	struct {
312 		uint8_t padding_l;
313 		unsigned char * __buf;
314 		uint8_t padding_r;
315 	} __stack;
316 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
317 	const size_t __len = 42;
318 	const size_t __idx __unused = __len - 1;
319 
320 	__stack.__buf = malloc(__bufsz);
321 
322 	bzero(__stack.__buf, __len);
323 #undef BUF
324 
325 }
326 
327 ATF_TC_WITHOUT_HEAD(bzero_heap_after_end);
328 ATF_TC_BODY(bzero_heap_after_end, tc)
329 {
330 #define BUF __stack.__buf
331 	struct {
332 		uint8_t padding_l;
333 		unsigned char * __buf;
334 		uint8_t padding_r;
335 	} __stack;
336 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
337 	const size_t __len = 42 + 1;
338 	const size_t __idx __unused = __len - 1;
339 	pid_t __child;
340 	int __status;
341 
342 	__child = fork();
343 	ATF_REQUIRE(__child >= 0);
344 	if (__child > 0)
345 		goto monitor;
346 
347 	/* Child */
348 	disable_coredumps();
349 	__stack.__buf = malloc(__bufsz);
350 
351 	bzero(__stack.__buf, __len);
352 	_exit(EX_SOFTWARE);	/* Should have aborted. */
353 
354 monitor:
355 	while (waitpid(__child, &__status, 0) != __child) {
356 		ATF_REQUIRE_EQ(EINTR, errno);
357 	}
358 
359 	if (!WIFSIGNALED(__status)) {
360 		switch (WEXITSTATUS(__status)) {
361 		case EX_SOFTWARE:
362 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
363 			break;
364 		case EX_OSERR:
365 			atf_tc_fail("setrlimit(2) failed");
366 			break;
367 		default:
368 			atf_tc_fail("child exited with status %d",
369 			    WEXITSTATUS(__status));
370 		}
371 	} else {
372 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
373 	}
374 #undef BUF
375 
376 }
377 
378 ATF_TC_WITHOUT_HEAD(explicit_bzero_before_end);
379 ATF_TC_BODY(explicit_bzero_before_end, tc)
380 {
381 #define BUF &__stack.__buf
382 	struct {
383 		uint8_t padding_l;
384 		unsigned char __buf[42];
385 		uint8_t padding_r;
386 	} __stack;
387 	const size_t __bufsz __unused = sizeof(__stack.__buf);
388 	const size_t __len = 42 - 1;
389 	const size_t __idx __unused = __len - 1;
390 
391 	explicit_bzero(__stack.__buf, __len);
392 #undef BUF
393 
394 }
395 
396 ATF_TC_WITHOUT_HEAD(explicit_bzero_end);
397 ATF_TC_BODY(explicit_bzero_end, tc)
398 {
399 #define BUF &__stack.__buf
400 	struct {
401 		uint8_t padding_l;
402 		unsigned char __buf[42];
403 		uint8_t padding_r;
404 	} __stack;
405 	const size_t __bufsz __unused = sizeof(__stack.__buf);
406 	const size_t __len = 42;
407 	const size_t __idx __unused = __len - 1;
408 
409 	explicit_bzero(__stack.__buf, __len);
410 #undef BUF
411 
412 }
413 
414 ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_before_end);
415 ATF_TC_BODY(explicit_bzero_heap_before_end, tc)
416 {
417 #define BUF __stack.__buf
418 	struct {
419 		uint8_t padding_l;
420 		unsigned char * __buf;
421 		uint8_t padding_r;
422 	} __stack;
423 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
424 	const size_t __len = 42 - 1;
425 	const size_t __idx __unused = __len - 1;
426 
427 	__stack.__buf = malloc(__bufsz);
428 
429 	explicit_bzero(__stack.__buf, __len);
430 #undef BUF
431 
432 }
433 
434 ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_end);
435 ATF_TC_BODY(explicit_bzero_heap_end, tc)
436 {
437 #define BUF __stack.__buf
438 	struct {
439 		uint8_t padding_l;
440 		unsigned char * __buf;
441 		uint8_t padding_r;
442 	} __stack;
443 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
444 	const size_t __len = 42;
445 	const size_t __idx __unused = __len - 1;
446 
447 	__stack.__buf = malloc(__bufsz);
448 
449 	explicit_bzero(__stack.__buf, __len);
450 #undef BUF
451 
452 }
453 
454 ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_after_end);
455 ATF_TC_BODY(explicit_bzero_heap_after_end, tc)
456 {
457 #define BUF __stack.__buf
458 	struct {
459 		uint8_t padding_l;
460 		unsigned char * __buf;
461 		uint8_t padding_r;
462 	} __stack;
463 	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
464 	const size_t __len = 42 + 1;
465 	const size_t __idx __unused = __len - 1;
466 	pid_t __child;
467 	int __status;
468 
469 	__child = fork();
470 	ATF_REQUIRE(__child >= 0);
471 	if (__child > 0)
472 		goto monitor;
473 
474 	/* Child */
475 	disable_coredumps();
476 	__stack.__buf = malloc(__bufsz);
477 
478 	explicit_bzero(__stack.__buf, __len);
479 	_exit(EX_SOFTWARE);	/* Should have aborted. */
480 
481 monitor:
482 	while (waitpid(__child, &__status, 0) != __child) {
483 		ATF_REQUIRE_EQ(EINTR, errno);
484 	}
485 
486 	if (!WIFSIGNALED(__status)) {
487 		switch (WEXITSTATUS(__status)) {
488 		case EX_SOFTWARE:
489 			atf_tc_fail("FORTIFY_SOURCE failed to abort");
490 			break;
491 		case EX_OSERR:
492 			atf_tc_fail("setrlimit(2) failed");
493 			break;
494 		default:
495 			atf_tc_fail("child exited with status %d",
496 			    WEXITSTATUS(__status));
497 		}
498 	} else {
499 		ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
500 	}
501 #undef BUF
502 
503 }
504 
505 ATF_TP_ADD_TCS(tp)
506 {
507 	ATF_TP_ADD_TC(tp, bcopy_before_end);
508 	ATF_TP_ADD_TC(tp, bcopy_end);
509 	ATF_TP_ADD_TC(tp, bcopy_heap_before_end);
510 	ATF_TP_ADD_TC(tp, bcopy_heap_end);
511 	ATF_TP_ADD_TC(tp, bcopy_heap_after_end);
512 	ATF_TP_ADD_TC(tp, bzero_before_end);
513 	ATF_TP_ADD_TC(tp, bzero_end);
514 	ATF_TP_ADD_TC(tp, bzero_heap_before_end);
515 	ATF_TP_ADD_TC(tp, bzero_heap_end);
516 	ATF_TP_ADD_TC(tp, bzero_heap_after_end);
517 	ATF_TP_ADD_TC(tp, explicit_bzero_before_end);
518 	ATF_TP_ADD_TC(tp, explicit_bzero_end);
519 	ATF_TP_ADD_TC(tp, explicit_bzero_heap_before_end);
520 	ATF_TP_ADD_TC(tp, explicit_bzero_heap_end);
521 	ATF_TP_ADD_TC(tp, explicit_bzero_heap_after_end);
522 	return (atf_no_error());
523 }
524