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