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