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