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