xref: /linux/tools/testing/selftests/nolibc/nolibc-test.c (revision 542fed2ef2ff7e580cc25efb174f5e1237e3b0eb)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 
3 #define _GNU_SOURCE
4 #define _LARGEFILE64_SOURCE
5 #define _FILE_OFFSET_BITS 64
6 
7 /* libc-specific include files
8  * The program may be built in 3 ways:
9  *   $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined
10  *   $(CC) -nostdlib -I/path/to/nolibc/sysroot  => _NOLIBC_* guards are present
11  *   $(CC) with default libc                    => NOLIBC* never defined
12  */
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <sys/auxv.h>
17 #include <sys/ioctl.h>
18 #include <sys/mman.h>
19 #include <sys/mount.h>
20 #include <sys/prctl.h>
21 #include <sys/ptrace.h>
22 #include <sys/random.h>
23 #include <sys/reboot.h>
24 #include <sys/resource.h>
25 #include <sys/sendfile.h>
26 #include <sys/stat.h>
27 #include <sys/syscall.h>
28 #include <sys/sysmacros.h>
29 #include <sys/time.h>
30 #include <sys/timerfd.h>
31 #include <sys/uio.h>
32 #include <sys/utsname.h>
33 #include <sys/wait.h>
34 #include <dirent.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <poll.h>
38 #include <sched.h>
39 #include <signal.h>
40 #include <stdarg.h>
41 #include <stddef.h>
42 #include <stdint.h>
43 #include <time.h>
44 #include <unistd.h>
45 #include <limits.h>
46 #include <ctype.h>
47 #include <stdbool.h>
48 #include <byteswap.h>
49 #include <endian.h>
50 #include <alloca.h>
51 
52 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
53 
54 #include "nolibc-test-linkage.h"
55 
56 /* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */
57 #define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
58 #define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
59 
60 /* will be used to test initialization of environ */
61 static char **test_envp;
62 
63 /* will be used to test initialization of argv */
64 static char **test_argv;
65 
66 /* will be used to test initialization of argc */
67 static int test_argc;
68 
69 /* will be used by some test cases as readable file, please don't write it */
70 static const char *argv0;
71 
72 /* will be used by constructor tests */
73 static int constructor_test_value;
74 
75 static const int is_le = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
76 
77 static const int is_nolibc =
78 #ifdef NOLIBC
79 	1
80 #else
81 	0
82 #endif
83 ;
84 
85 static const int is_glibc =
86 #ifdef __GLIBC__
87 	1
88 #else
89 	0
90 #endif
91 ;
92 
93 #if !defined(NOLIBC)
94 /* Some disabled tests may not compile. */
95 
96 /* strlcat() and strlcpy() may not be in the system headers. */
97 #undef strlcat
98 #undef strlcpy
99 #define strlcat(d, s, l) 0
100 #define strlcpy(d, s, l) 0
101 
102 /* readdir_r() is likely to be marked deprecated */
103 #undef readdir_r
104 #define readdir_r(dir, dirent, result) ((errno = EINVAL), -1)
105 
106 #define _syscall(...) 0
107 #endif
108 
109 /* definition of a series of tests */
110 struct test {
111 	const char *name;              /* test name */
112 	int (*func)(int min, int max); /* handler */
113 };
114 
115 #ifndef _NOLIBC_STDLIB_H
itoa(int i)116 char *itoa(int i)
117 {
118 	static char buf[12];
119 	int ret;
120 
121 	ret = snprintf(buf, sizeof(buf), "%d", i);
122 	return (ret >= 0 && ret < sizeof(buf)) ? buf : "#err";
123 }
124 #endif
125 
126 #define CASE_ERR(err) \
127 	case err: return #err
128 
129 /* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0,
130  * or the decimal value for less common ones.
131  */
errorname(int err)132 static const char *errorname(int err)
133 {
134 	switch (err) {
135 	case 0: return "SUCCESS";
136 	CASE_ERR(EPERM);
137 	CASE_ERR(ENOENT);
138 	CASE_ERR(ESRCH);
139 	CASE_ERR(EINTR);
140 	CASE_ERR(EIO);
141 	CASE_ERR(ENXIO);
142 	CASE_ERR(E2BIG);
143 	CASE_ERR(ENOEXEC);
144 	CASE_ERR(EBADF);
145 	CASE_ERR(ECHILD);
146 	CASE_ERR(EAGAIN);
147 	CASE_ERR(ENOMEM);
148 	CASE_ERR(EACCES);
149 	CASE_ERR(EFAULT);
150 	CASE_ERR(ENOTBLK);
151 	CASE_ERR(EBUSY);
152 	CASE_ERR(EEXIST);
153 	CASE_ERR(EXDEV);
154 	CASE_ERR(ENODEV);
155 	CASE_ERR(ENOTDIR);
156 	CASE_ERR(EISDIR);
157 	CASE_ERR(EINVAL);
158 	CASE_ERR(ENFILE);
159 	CASE_ERR(EMFILE);
160 	CASE_ERR(ENOTTY);
161 	CASE_ERR(ETXTBSY);
162 	CASE_ERR(EFBIG);
163 	CASE_ERR(ENOSPC);
164 	CASE_ERR(ESPIPE);
165 	CASE_ERR(EROFS);
166 	CASE_ERR(EMLINK);
167 	CASE_ERR(EPIPE);
168 	CASE_ERR(EDOM);
169 	CASE_ERR(ERANGE);
170 	CASE_ERR(ENOSYS);
171 	CASE_ERR(EOVERFLOW);
172 	default:
173 		return itoa(err);
174 	}
175 }
176 
177 enum RESULT {
178 	OK,
179 	FAIL,
180 	SKIPPED,
181 };
182 
result(int llen,enum RESULT r)183 static void result(int llen, enum RESULT r)
184 {
185 	const char *msg;
186 
187 	if (r == OK)
188 		msg = "  [OK]";
189 	else if (r == SKIPPED)
190 		msg = "[SKIPPED]";
191 	else
192 		msg = " [FAIL]";
193 
194 	llen = 64 - llen;
195 	if (llen < 0)
196 		llen = 0;
197 	printf("%*s%s\n", llen, "", msg);
198 }
199 
200 /* The tests below are intended to be used by the macroes, which evaluate
201  * expression <expr>, print the status to stdout, and update the "ret"
202  * variable to count failures. The functions themselves return the number
203  * of failures, thus either 0 or 1.
204  */
205 
206 #define EXPECT_ZR(cond, expr)				\
207 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_zr(expr, llen); } while (0)
208 
209 static __attribute__((unused))
expect_zr(int expr,int llen)210 int expect_zr(int expr, int llen)
211 {
212 	int ret = !(expr == 0);
213 
214 	llen += printf(" = %d ", expr);
215 	result(llen, ret ? FAIL : OK);
216 	return ret;
217 }
218 
219 
220 #define EXPECT_NZ(cond, expr)				\
221 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_nz(expr, llen); } while (0)
222 
223 static __attribute__((unused))
expect_nz(int expr,int llen)224 int expect_nz(int expr, int llen)
225 {
226 	int ret = !(expr != 0);
227 
228 	llen += printf(" = %d ", expr);
229 	result(llen, ret ? FAIL : OK);
230 	return ret;
231 }
232 
233 
234 #define EXPECT_EQ(cond, expr, val)				\
235 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_eq(expr, llen, val); } while (0)
236 
237 static __attribute__((unused))
expect_eq(uint64_t expr,int llen,uint64_t val)238 int expect_eq(uint64_t expr, int llen, uint64_t val)
239 {
240 	int ret = !(expr == val);
241 
242 	llen += printf(" = %lld ", (long long)expr);
243 	result(llen, ret ? FAIL : OK);
244 	return ret;
245 }
246 
247 
248 #define EXPECT_NE(cond, expr, val)				\
249 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ne(expr, llen, val); } while (0)
250 
251 static __attribute__((unused))
expect_ne(int expr,int llen,int val)252 int expect_ne(int expr, int llen, int val)
253 {
254 	int ret = !(expr != val);
255 
256 	llen += printf(" = %d ", expr);
257 	result(llen, ret ? FAIL : OK);
258 	return ret;
259 }
260 
261 
262 #define EXPECT_GE(cond, expr, val)				\
263 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ge(expr, llen, val); } while (0)
264 
265 static __attribute__((unused))
expect_ge(int expr,int llen,int val)266 int expect_ge(int expr, int llen, int val)
267 {
268 	int ret = !(expr >= val);
269 
270 	llen += printf(" = %d ", expr);
271 	result(llen, ret ? FAIL : OK);
272 	return ret;
273 }
274 
275 
276 #define EXPECT_GT(cond, expr, val)				\
277 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_gt(expr, llen, val); } while (0)
278 
279 static __attribute__((unused))
expect_gt(int expr,int llen,int val)280 int expect_gt(int expr, int llen, int val)
281 {
282 	int ret = !(expr > val);
283 
284 	llen += printf(" = %d ", expr);
285 	result(llen, ret ? FAIL : OK);
286 	return ret;
287 }
288 
289 
290 #define EXPECT_LE(cond, expr, val)				\
291 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_le(expr, llen, val); } while (0)
292 
293 static __attribute__((unused))
expect_le(int expr,int llen,int val)294 int expect_le(int expr, int llen, int val)
295 {
296 	int ret = !(expr <= val);
297 
298 	llen += printf(" = %d ", expr);
299 	result(llen, ret ? FAIL : OK);
300 	return ret;
301 }
302 
303 
304 #define EXPECT_LT(cond, expr, val)				\
305 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_lt(expr, llen, val); } while (0)
306 
307 static __attribute__((unused))
expect_lt(int expr,int llen,int val)308 int expect_lt(int expr, int llen, int val)
309 {
310 	int ret = !(expr < val);
311 
312 	llen += printf(" = %d ", expr);
313 	result(llen, ret ? FAIL : OK);
314 	return ret;
315 }
316 
317 
318 #define EXPECT_SYSZR(cond, expr)				\
319 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syszr(expr, llen); } while (0)
320 
321 static __attribute__((unused))
expect_syszr(int expr,int llen)322 int expect_syszr(int expr, int llen)
323 {
324 	int ret = 0;
325 
326 	if (expr) {
327 		ret = 1;
328 		llen += printf(" = %d %s ", expr, errorname(errno));
329 		result(llen, FAIL);
330 	} else {
331 		llen += printf(" = %d ", expr);
332 		result(llen, OK);
333 	}
334 	return ret;
335 }
336 
337 
338 #define EXPECT_SYSEQ(cond, expr, val)				\
339 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syseq(expr, llen, val); } while (0)
340 
341 static __attribute__((unused))
expect_syseq(int expr,int llen,int val)342 int expect_syseq(int expr, int llen, int val)
343 {
344 	int ret = 0;
345 
346 	if (expr != val) {
347 		ret = 1;
348 		llen += printf(" = %d %s ", expr, errorname(errno));
349 		result(llen, FAIL);
350 	} else {
351 		llen += printf(" = %d ", expr);
352 		result(llen, OK);
353 	}
354 	return ret;
355 }
356 
357 
358 #define EXPECT_SYSNE(cond, expr, val)				\
359 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_sysne(expr, llen, val); } while (0)
360 
361 static __attribute__((unused))
expect_sysne(int expr,int llen,int val)362 int expect_sysne(int expr, int llen, int val)
363 {
364 	int ret = 0;
365 
366 	if (expr == val) {
367 		ret = 1;
368 		llen += printf(" = %d %s ", expr, errorname(errno));
369 		result(llen, FAIL);
370 	} else {
371 		llen += printf(" = %d ", expr);
372 		result(llen, OK);
373 	}
374 	return ret;
375 }
376 
377 
378 #define EXPECT_SYSER2(cond, expr, expret, experr1, experr2)		\
379 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syserr2(expr, expret, experr1, experr2, llen); } while (0)
380 
381 #define EXPECT_SYSER(cond, expr, expret, experr)			\
382 	EXPECT_SYSER2(cond, expr, expret, experr, 0)
383 
384 static __attribute__((unused))
expect_syserr2(int expr,int expret,int experr1,int experr2,int llen)385 int expect_syserr2(int expr, int expret, int experr1, int experr2, int llen)
386 {
387 	int ret = 0;
388 	int _errno = errno;
389 
390 	llen += printf(" = %d %s ", expr, errorname(_errno));
391 	if (expr != expret || (_errno != experr1 && _errno != experr2)) {
392 		ret = 1;
393 		if (experr2 == 0)
394 			llen += printf(" != (%d %s) ", expret, errorname(experr1));
395 		else
396 			llen += printf(" != (%d %s %s) ", expret, errorname(experr1), errorname(experr2));
397 		result(llen, FAIL);
398 	} else {
399 		result(llen, OK);
400 	}
401 	return ret;
402 }
403 
404 
405 #define EXPECT_PTRZR(cond, expr)				\
406 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrzr(expr, llen); } while (0)
407 
408 static __attribute__((unused))
expect_ptrzr(const void * expr,int llen)409 int expect_ptrzr(const void *expr, int llen)
410 {
411 	int ret = 0;
412 
413 	llen += printf(" = <%p> ", expr);
414 	if (expr) {
415 		ret = 1;
416 		result(llen, FAIL);
417 	} else {
418 		result(llen, OK);
419 	}
420 	return ret;
421 }
422 
423 
424 #define EXPECT_PTRNZ(cond, expr)				\
425 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrnz(expr, llen); } while (0)
426 
427 static __attribute__((unused))
expect_ptrnz(const void * expr,int llen)428 int expect_ptrnz(const void *expr, int llen)
429 {
430 	int ret = 0;
431 
432 	llen += printf(" = <%p> ", expr);
433 	if (!expr) {
434 		ret = 1;
435 		result(llen, FAIL);
436 	} else {
437 		result(llen, OK);
438 	}
439 	return ret;
440 }
441 
442 #define EXPECT_PTREQ(cond, expr, cmp)				\
443 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptreq(expr, llen, cmp); } while (0)
444 
445 static __attribute__((unused))
expect_ptreq(const void * expr,int llen,const void * cmp)446 int expect_ptreq(const void *expr, int llen, const void *cmp)
447 {
448 	int ret = 0;
449 
450 	llen += printf(" = <%p> ", expr);
451 	if (expr != cmp) {
452 		ret = 1;
453 		result(llen, FAIL);
454 	} else {
455 		result(llen, OK);
456 	}
457 	return ret;
458 }
459 
460 #define EXPECT_PTRNE(cond, expr, cmp)				\
461 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrne(expr, llen, cmp); } while (0)
462 
463 static __attribute__((unused))
expect_ptrne(const void * expr,int llen,const void * cmp)464 int expect_ptrne(const void *expr, int llen, const void *cmp)
465 {
466 	int ret = 0;
467 
468 	llen += printf(" = <%p> ", expr);
469 	if (expr == cmp) {
470 		ret = 1;
471 		result(llen, FAIL);
472 	} else {
473 		result(llen, OK);
474 	}
475 	return ret;
476 }
477 
478 #define EXPECT_PTRGE(cond, expr, cmp)				\
479 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrge(expr, llen, cmp); } while (0)
480 
481 static __attribute__((unused))
expect_ptrge(const void * expr,int llen,const void * cmp)482 int expect_ptrge(const void *expr, int llen, const void *cmp)
483 {
484 	int ret = !(expr >= cmp);
485 
486 	llen += printf(" = <%p> ", expr);
487 	result(llen, ret ? FAIL : OK);
488 	return ret;
489 }
490 
491 #define EXPECT_PTRGT(cond, expr, cmp)				\
492 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrgt(expr, llen, cmp); } while (0)
493 
494 static __attribute__((unused))
expect_ptrgt(const void * expr,int llen,const void * cmp)495 int expect_ptrgt(const void *expr, int llen, const void *cmp)
496 {
497 	int ret = !(expr > cmp);
498 
499 	llen += printf(" = <%p> ", expr);
500 	result(llen, ret ? FAIL : OK);
501 	return ret;
502 }
503 
504 
505 #define EXPECT_PTRLE(cond, expr, cmp)				\
506 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrle(expr, llen, cmp); } while (0)
507 
508 static __attribute__((unused))
expect_ptrle(const void * expr,int llen,const void * cmp)509 int expect_ptrle(const void *expr, int llen, const void *cmp)
510 {
511 	int ret = !(expr <= cmp);
512 
513 	llen += printf(" = <%p> ", expr);
514 	result(llen, ret ? FAIL : OK);
515 	return ret;
516 }
517 
518 
519 #define EXPECT_PTRLT(cond, expr, cmp)				\
520 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrlt(expr, llen, cmp); } while (0)
521 
522 static __attribute__((unused))
expect_ptrlt(const void * expr,int llen,const void * cmp)523 int expect_ptrlt(const void *expr, int llen, const void *cmp)
524 {
525 	int ret = !(expr < cmp);
526 
527 	llen += printf(" = <%p> ", expr);
528 	result(llen, ret ? FAIL : OK);
529 	return ret;
530 }
531 
532 #define EXPECT_PTRER2(cond, expr, expret, experr1, experr2)		\
533 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrerr2(expr, expret, experr1, experr2, llen); } while (0)
534 
535 #define EXPECT_PTRER(cond, expr, expret, experr)			\
536 	EXPECT_PTRER2(cond, expr, expret, experr, 0)
537 
538 static __attribute__((unused))
expect_ptrerr2(const void * expr,const void * expret,int experr1,int experr2,int llen)539 int expect_ptrerr2(const void *expr, const void *expret, int experr1, int experr2, int llen)
540 {
541 	int ret = 0;
542 	int _errno = errno;
543 
544 	llen += printf(" = <%p> %s ", expr, errorname(_errno));
545 	if (expr != expret || (_errno != experr1 && _errno != experr2)) {
546 		ret = 1;
547 		if (experr2 == 0)
548 			llen += printf(" != (<%p> %s) ", expret, errorname(experr1));
549 		else
550 			llen += printf(" != (<%p> %s %s) ", expret, errorname(experr1), errorname(experr2));
551 		result(llen, FAIL);
552 	} else {
553 		result(llen, OK);
554 	}
555 	return ret;
556 }
557 
558 #define EXPECT_STRZR(cond, expr)				\
559 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strzr(expr, llen); } while (0)
560 
561 static __attribute__((unused))
expect_strzr(const char * expr,int llen)562 int expect_strzr(const char *expr, int llen)
563 {
564 	int ret = 0;
565 
566 	llen += printf(" = <%s> ", expr ? expr : "(null)");
567 	if (expr) {
568 		ret = 1;
569 		result(llen, FAIL);
570 	} else {
571 		result(llen, OK);
572 	}
573 	return ret;
574 }
575 
576 
577 #define EXPECT_STRNZ(cond, expr)				\
578 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strnz(expr, llen); } while (0)
579 
580 static __attribute__((unused))
expect_strnz(const char * expr,int llen)581 int expect_strnz(const char *expr, int llen)
582 {
583 	int ret = 0;
584 
585 	llen += printf(" = <%s> ", expr ? expr : "(null)");
586 	if (!expr) {
587 		ret = 1;
588 		result(llen, FAIL);
589 	} else {
590 		result(llen, OK);
591 	}
592 	return ret;
593 }
594 
595 
596 #define EXPECT_STREQ(cond, expr, cmp)				\
597 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_streq(expr, llen, cmp); } while (0)
598 
599 static __attribute__((unused))
expect_streq(const char * expr,int llen,const char * cmp)600 int expect_streq(const char *expr, int llen, const char *cmp)
601 {
602 	int ret = 0;
603 
604 	llen += printf(" = <%s> ", expr);
605 	if (strcmp(expr, cmp) != 0) {
606 		ret = 1;
607 		result(llen, FAIL);
608 	} else {
609 		result(llen, OK);
610 	}
611 	return ret;
612 }
613 
614 
615 #define EXPECT_STRNE(cond, expr, cmp)				\
616 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strne(expr, llen, cmp); } while (0)
617 
618 static __attribute__((unused))
expect_strne(const char * expr,int llen,const char * cmp)619 int expect_strne(const char *expr, int llen, const char *cmp)
620 {
621 	int ret = 0;
622 
623 	llen += printf(" = <%s> ", expr);
624 	if (strcmp(expr, cmp) == 0) {
625 		ret = 1;
626 		result(llen, FAIL);
627 	} else {
628 		result(llen, OK);
629 	}
630 	return ret;
631 }
632 
633 #define EXPECT_STRBUFEQ(cond, expr, buf, val, cmp)				\
634 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_str_buf_eq(expr, buf, val, llen, cmp); } while (0)
635 
636 static __attribute__((unused))
expect_str_buf_eq(size_t expr,const char * buf,size_t val,int llen,const char * cmp)637 int expect_str_buf_eq(size_t expr, const char *buf, size_t val, int llen, const char *cmp)
638 {
639 	llen += printf(" = %lu <%s> ", (unsigned long)expr, buf);
640 	if (strcmp(buf, cmp) != 0) {
641 		result(llen, FAIL);
642 		return 1;
643 	}
644 	if (expr != val) {
645 		result(llen, FAIL);
646 		return 1;
647 	}
648 
649 	result(llen, OK);
650 	return 0;
651 }
652 
653 enum strtox_func {
654 	strtox_func_strtol,
655 	strtox_func_strtoul,
656 };
657 
658 #define EXPECT_STRTOX(cond, func, input, base, expected, chars, expected_errno)				\
659 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strtox(llen, strtox_func_ ## func, input, base, expected, chars, expected_errno); } while (0)
660 
661 static __attribute__((unused))
expect_strtox(int llen,enum strtox_func func,const char * input,int base,intmax_t expected,int expected_chars,int expected_errno)662 int expect_strtox(int llen, enum strtox_func func, const char *input, int base, intmax_t expected, int expected_chars, int expected_errno)
663 {
664 	char *endptr;
665 	int actual_errno, actual_chars;
666 	intmax_t r;
667 
668 	errno = 0;
669 	if (func == strtox_func_strtol) {
670 		r = strtol(input, &endptr, base);
671 	} else if (func == strtox_func_strtoul) {
672 		r = strtoul(input, &endptr, base);
673 	} else {
674 		result(llen, FAIL);
675 		return 1;
676 	}
677 	actual_errno = errno;
678 	actual_chars = endptr - input;
679 
680 	llen += printf(" %lld = %lld", (long long)expected, (long long)r);
681 	if (r != expected) {
682 		result(llen, FAIL);
683 		return 1;
684 	}
685 	if (expected_chars == -1) {
686 		if (*endptr != '\0') {
687 			result(llen, FAIL);
688 			return 1;
689 		}
690 	} else if (expected_chars != actual_chars) {
691 		result(llen, FAIL);
692 		return 1;
693 	}
694 	if (actual_errno != expected_errno) {
695 		result(llen, FAIL);
696 		return 1;
697 	}
698 
699 	result(llen, OK);
700 	return 0;
701 }
702 
703 /* declare tests based on line numbers. There must be exactly one test per line. */
704 #define CASE_TEST(name) \
705 	case __LINE__: llen += printf("%d %s", test, #name);
706 
707 __attribute__((constructor))
constructor1(void)708 static void constructor1(void)
709 {
710 	constructor_test_value |= 1 << 0;
711 }
712 
713 __attribute__((constructor))
constructor2(int argc,char ** argv,char ** envp)714 static void constructor2(int argc, char **argv, char **envp)
715 {
716 	if (argc && argv && envp)
717 		constructor_test_value |= 1 << 1;
718 }
719 
test_program_invocation_name(void)720 int test_program_invocation_name(void)
721 {
722 	char buf[100];
723 	char *dirsep;
724 	ssize_t r;
725 	int fd;
726 
727 	fd = open("/proc/self/cmdline", O_RDONLY);
728 	if (fd == -1)
729 		return 1;
730 
731 	r = read(fd, buf, sizeof(buf));
732 	close(fd);
733 	if (r < 1 || r == sizeof(buf))
734 		return 1;
735 
736 	buf[r - 1] = '\0';
737 
738 	if (strcmp(program_invocation_name, buf) != 0)
739 		return 1;
740 
741 	dirsep = strrchr(buf, '/');
742 	if (!dirsep || dirsep[1] == '\0')
743 		return 1;
744 
745 	if (strcmp(program_invocation_short_name, dirsep + 1) != 0)
746 		return 1;
747 
748 	return 0;
749 }
750 
run_startup(int min,int max)751 int run_startup(int min, int max)
752 {
753 	int test;
754 	int ret = 0;
755 	/* kernel at least passes HOME and TERM, shell passes more */
756 	int env_total = 2;
757 	/* checking NULL for argv/argv0, environ and _auxv is not enough, let's compare with sbrk(0) or &end */
758 	extern char end;
759 	char *brk = sbrk(0) != (void *)-1 ? sbrk(0) : &end;
760 #if defined(__alpha__)
761 	/* the ordering above does not work on an alpha kernel due to STACK_TOP != TASK_SIZE */
762 	brk = NULL;
763 #endif
764 	/* differ from nolibc, both glibc and musl have no global _auxv */
765 	const unsigned long *test_auxv = (void *)-1;
766 #ifdef NOLIBC
767 	test_auxv = _auxv;
768 #endif
769 	bool proc = access("/proc", R_OK) == 0;
770 
771 	for (test = min; test >= 0 && test <= max; test++) {
772 		int llen = 0; /* line length */
773 
774 		/* avoid leaving empty lines below, this will insert holes into
775 		 * test numbers.
776 		 */
777 		switch (test + __LINE__ + 1) {
778 		CASE_TEST(argc);             EXPECT_GE(1, test_argc, 1); break;
779 		CASE_TEST(argv_addr);        EXPECT_PTRGT(1, test_argv, brk); break;
780 		CASE_TEST(argv_environ);     EXPECT_PTRLT(1, test_argv, environ); break;
781 		CASE_TEST(argv_total);       EXPECT_EQ(1, environ - test_argv - 1, test_argc ?: 1); break;
782 		CASE_TEST(argv0_addr);       EXPECT_PTRGT(1, argv0, brk); break;
783 		CASE_TEST(argv0_str);        EXPECT_STRNZ(1, argv0 > brk ? argv0 : NULL); break;
784 		CASE_TEST(argv0_len);        EXPECT_GE(1,  argv0 > brk ? strlen(argv0) : 0, 1); break;
785 		CASE_TEST(environ_addr);     EXPECT_PTRGT(1, environ, brk); break;
786 		CASE_TEST(environ_envp);     EXPECT_PTREQ(1, environ, test_envp); break;
787 		CASE_TEST(environ_auxv);     EXPECT_PTRLT(test_auxv != (void *)-1, environ, test_auxv); break;
788 		CASE_TEST(environ_total);    EXPECT_GE(test_auxv != (void *)-1, (void *)test_auxv - (void *)environ - 1, env_total); break;
789 		CASE_TEST(environ_HOME);     EXPECT_PTRNZ(1, getenv("HOME")); break;
790 		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;
791 		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;
792 		CASE_TEST(constructor);      EXPECT_EQ(is_nolibc, constructor_test_value, 0x3); break;
793 		CASE_TEST(linkage_errno);    EXPECT_PTREQ(1, linkage_test_errno_addr(), &errno); break;
794 		CASE_TEST(linkage_constr);   EXPECT_EQ(1, linkage_test_constructor_test_value, 0x3); break;
795 		CASE_TEST(prog_name);        EXPECT_ZR(proc, test_program_invocation_name()); break;
796 		case __LINE__:
797 			return ret; /* must be last */
798 		/* note: do not set any defaults so as to permit holes above */
799 		}
800 	}
801 	return ret;
802 }
803 
804 
805 /* used by some syscall tests below */
test_getdents64(const char * dir)806 int test_getdents64(const char *dir)
807 {
808 	char buffer[4096];
809 	int fd, ret;
810 	int err;
811 
812 	ret = fd = open(dir, O_RDONLY | O_DIRECTORY);
813 	if (ret < 0)
814 		return ret;
815 
816 	ret = getdents64(fd, (void *)buffer, sizeof(buffer));
817 	err = errno;
818 	close(fd);
819 
820 	errno = err;
821 	return ret;
822 }
823 
test_dirent(void)824 static int test_dirent(void)
825 {
826 	int comm = 0, cmdline = 0;
827 	struct dirent dirent, *result;
828 	DIR *dir;
829 	int ret;
830 
831 	dir = opendir("/proc/self");
832 	if (!dir)
833 		return 1;
834 
835 	while (1) {
836 		errno = 0;
837 		ret = readdir_r(dir, &dirent, &result);
838 		if (ret != 0)
839 			return 1;
840 		if (!result)
841 			break;
842 
843 		if (strcmp(dirent.d_name, "comm") == 0)
844 			comm++;
845 		else if (strcmp(dirent.d_name, "cmdline") == 0)
846 			cmdline++;
847 	}
848 
849 	if (errno)
850 		return 1;
851 
852 	ret = closedir(dir);
853 	if (ret)
854 		return 1;
855 
856 	if (comm != 1 || cmdline != 1)
857 		return 1;
858 
859 	return 0;
860 }
861 
test_getcwd(void)862 int test_getcwd(void)
863 {
864 	char cwd_syscall[PATH_MAX];
865 	char cwd_proc[PATH_MAX];
866 	ssize_t len;
867 
868 	/* Read where the link /proc/self/cwd points */
869 	len = readlink("/proc/self/cwd", cwd_proc, sizeof(cwd_proc) - 1);
870 	if (len <= 0)
871 		return __LINE__;
872 
873 	/* Terminate the string from readlink() */
874 	cwd_proc[len] = '\0';
875 
876 	/* Get the cwd via syscall */
877 	if (getcwd(cwd_syscall, sizeof(cwd_syscall)) == NULL)
878 		return __LINE__;
879 
880 	/* Fail if they aren't the same */
881 	if (strcmp(cwd_proc, cwd_syscall) != 0)
882 		return __LINE__;
883 
884 	/* Try getcwd() with NULL for the buffer,
885 	 * should return NULL and an error in errno.
886 	 * Other libc's allow this by allocating a buffer
887 	 * internally.
888 	 */
889 	if (is_nolibc) {
890 		errno = 0;
891 		if (getcwd(NULL, 0) != NULL || !errno)
892 			return __LINE__;
893 	}
894 
895 	/* Try getcwd() with a buffer but make the size 0,
896 	 * should return NULL and an error in errno.
897 	 */
898 	errno = 0;
899 	if (getcwd(cwd_syscall, 0) != NULL || !errno)
900 		return __LINE__;
901 
902 	/* Try getcwd() with a buffer but make the size 1,
903 	 * should return NULL and an error in errno because
904 	 * the string written to the buffer is terminated
905 	 * so you need at least 2 bytes even for "/".
906 	 */
907 	errno = 0;
908 	if (getcwd(cwd_syscall, 1) != NULL || !errno)
909 		return __LINE__;
910 
911 	return 0;
912 }
913 
test_getrandom(void)914 int test_getrandom(void)
915 {
916 	uint64_t rng = 0;
917 	ssize_t ret;
918 
919 	ret = getrandom(&rng, sizeof(rng), GRND_NONBLOCK);
920 	if (ret == -1 && errno == EAGAIN)
921 		return 0; /* No entropy available yet */
922 
923 	if (ret != sizeof(rng))
924 		return ret;
925 
926 	if (!rng) {
927 		errno = EINVAL;
928 		return -1;
929 	}
930 
931 	return 0;
932 }
933 
test_getpagesize(void)934 int test_getpagesize(void)
935 {
936 	int x = getpagesize();
937 	int c;
938 
939 	if (x < 0)
940 		return x;
941 
942 #if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
943 	/*
944 	 * x86 family is always 4K page.
945 	 */
946 	c = (x == 4096);
947 #elif defined(__aarch64__)
948 	/*
949 	 * Linux aarch64 supports three values of page size: 4K, 16K, and 64K
950 	 * which are selected at kernel compilation time.
951 	 */
952 	c = (x == 4096 || x == (16 * 1024) || x == (64 * 1024));
953 #else
954 	/*
955 	 * Assuming other architectures must have at least 4K page.
956 	 */
957 	c = (x >= 4096);
958 #endif
959 
960 	return !c;
961 }
962 
test_file_stream(void)963 int test_file_stream(void)
964 {
965 	FILE *f;
966 	int r;
967 
968 	f = fopen("/dev/null", "r");
969 	if (!f)
970 		return -1;
971 
972 	errno = 0;
973 	r = fwrite("foo", 1, 3, f);
974 	if (r != 0 || ((is_nolibc || is_glibc) && errno != EBADF)) {
975 		fclose(f);
976 		return -1;
977 	}
978 
979 	r = fclose(f);
980 	if (r == EOF)
981 		return -1;
982 
983 	return 0;
984 }
985 
test_file_stream_wsr(void)986 int test_file_stream_wsr(void)
987 {
988 	const char dataout[] = "foo";
989 	const size_t datasz = sizeof(dataout);
990 	char datain[datasz];
991 	int fd, r;
992 	FILE *f;
993 
994 	fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
995 	if (fd == -1)
996 		return -1;
997 
998 	f = fdopen(fd, "w+");
999 	if (!f)
1000 		return -1;
1001 
1002 	errno = 0;
1003 	r = fwrite(dataout, 1, datasz, f);
1004 	if (r != datasz)
1005 		return -1;
1006 
1007 	/* Attempt to read from the file without rewinding,
1008 	 * we should read 0 items.
1009 	 */
1010 	r = fread(datain, 1, datasz, f);
1011 	if (r)
1012 		return -1;
1013 
1014 	/* Rewind the file to the start */
1015 	r = fseek(f, 0, SEEK_SET);
1016 	if (r)
1017 		return -1;
1018 
1019 	/* Attempt to read back more than was written to
1020 	 * make sure we handle short reads properly.
1021 	 * fread() should return the number of complete items.
1022 	 */
1023 	r = fread(datain, 1, datasz + 1, f);
1024 	if (r != datasz)
1025 		return -1;
1026 
1027 	/* Data we read should match the data we just wrote */
1028 	if (memcmp(datain, dataout, datasz) != 0)
1029 		return -1;
1030 
1031 	r = fclose(f);
1032 	if (r)
1033 		return -1;
1034 
1035 	return 0;
1036 }
1037 
1038 enum fork_type {
1039 	FORK_STANDARD,
1040 	FORK_VFORK,
1041 };
1042 
test_fork(enum fork_type type)1043 int test_fork(enum fork_type type)
1044 {
1045 	int status;
1046 	pid_t pid;
1047 
1048 	/* flush the printf buffer to avoid child flush it */
1049 	fflush(stdout);
1050 	fflush(stderr);
1051 
1052 	switch (type) {
1053 	case FORK_STANDARD:
1054 		pid = fork();
1055 		break;
1056 	case FORK_VFORK:
1057 		pid = vfork();
1058 		break;
1059 	default:
1060 		return 1;
1061 	}
1062 
1063 	switch (pid) {
1064 	case -1:
1065 		return 1;
1066 
1067 	case 0:
1068 		_exit(123);
1069 
1070 	default:
1071 		pid = waitpid(pid, &status, 0);
1072 
1073 		return pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 123;
1074 	}
1075 }
1076 
test_ftruncate(void)1077 int test_ftruncate(void)
1078 {
1079 	struct stat stat_buf;
1080 	int ret, fd;
1081 
1082 	ret = ftruncate(-1, 0);
1083 	if (ret != -1 || errno != EBADF) {
1084 		errno = EINVAL;
1085 		return __LINE__;
1086 	}
1087 
1088 	fd = memfd_create(__func__, 0);
1089 	if (fd == -1)
1090 		return __LINE__;
1091 
1092 	/*
1093 	 * This also tests that the high 32-bit half is passed through correctly.
1094 	 * If it gets lost, the kernel will see a positive number and not fail.
1095 	 */
1096 	ret = ftruncate(fd, -1);
1097 	if (!(ret == -1 && errno == EINVAL)) {
1098 		if (ret == 0)
1099 			errno = EINVAL;
1100 		ret = __LINE__;
1101 		goto end;
1102 	}
1103 
1104 	ret = ftruncate(fd, 42);
1105 	if (ret != 0) {
1106 		ret = __LINE__;
1107 		goto end;
1108 	}
1109 
1110 	ret = fstat(fd, &stat_buf);
1111 	if (ret != 0) {
1112 		ret = __LINE__;
1113 		goto end;
1114 	}
1115 
1116 	if (stat_buf.st_size != 42) {
1117 		errno = EINVAL;
1118 		ret = __LINE__;
1119 		goto end;
1120 	}
1121 
1122 end:
1123 	close(fd);
1124 
1125 	return ret;
1126 }
1127 
test_stat_timestamps(void)1128 int test_stat_timestamps(void)
1129 {
1130 	struct stat st;
1131 
1132 	if (sizeof(st.st_atim.tv_sec) != sizeof(st.st_atime))
1133 		return 1;
1134 
1135 	if (stat("/proc/self/", &st) && stat(argv0, &st) && stat("/", &st))
1136 		return 1;
1137 
1138 	if (st.st_atim.tv_sec != st.st_atime || st.st_atim.tv_nsec > 1000000000)
1139 		return 1;
1140 
1141 	if (st.st_mtim.tv_sec != st.st_mtime || st.st_mtim.tv_nsec > 1000000000)
1142 		return 1;
1143 
1144 	if (st.st_ctim.tv_sec != st.st_ctime || st.st_ctim.tv_nsec > 1000000000)
1145 		return 1;
1146 
1147 	return 0;
1148 }
1149 
test_timer(void)1150 int test_timer(void)
1151 {
1152 	struct itimerspec timerspec;
1153 	struct sigevent evp;
1154 	timer_t timer;
1155 	int ret;
1156 
1157 	evp.sigev_notify = SIGEV_NONE;
1158 
1159 	ret = timer_create(CLOCK_MONOTONIC, &evp, &timer);
1160 	if (ret)
1161 		return ret;
1162 
1163 	timerspec = (struct itimerspec) {
1164 		.it_value.tv_sec = 1000000,
1165 	};
1166 	ret = timer_settime(timer, 0, &timerspec, NULL);
1167 	if (ret)
1168 		goto err;
1169 
1170 	timerspec = (struct itimerspec) {
1171 		.it_value.tv_sec = -1,
1172 		.it_value.tv_nsec = -1,
1173 		.it_interval.tv_sec = -1,
1174 		.it_interval.tv_nsec = -1,
1175 	};
1176 	ret = timer_gettime(timer, &timerspec);
1177 	if (ret)
1178 		goto err;
1179 
1180 	errno = EINVAL;
1181 	ret = -1;
1182 
1183 	if (timerspec.it_interval.tv_sec || timerspec.it_interval.tv_nsec)
1184 		goto err;
1185 
1186 	if (timerspec.it_value.tv_sec > 1000000)
1187 		goto err;
1188 
1189 	ret = timer_delete(timer);
1190 	if (ret)
1191 		return ret;
1192 
1193 	return 0;
1194 
1195 err:
1196 	timer_delete(timer);
1197 	return ret;
1198 }
1199 
test_timerfd(void)1200 int test_timerfd(void)
1201 {
1202 	struct itimerspec timerspec;
1203 	int timer, ret;
1204 
1205 	timer = timerfd_create(CLOCK_MONOTONIC, 0);
1206 	if (timer == -1)
1207 		return -1;
1208 
1209 	timerspec = (struct itimerspec) {
1210 		.it_value.tv_sec = 1000000,
1211 	};
1212 	ret = timerfd_settime(timer, 0, &timerspec, NULL);
1213 	if (ret)
1214 		goto err;
1215 
1216 	timerspec = (struct itimerspec) {
1217 		.it_value.tv_sec = -1,
1218 		.it_value.tv_nsec = -1,
1219 		.it_interval.tv_sec = -1,
1220 		.it_interval.tv_nsec = -1,
1221 	};
1222 	ret = timerfd_gettime(timer, &timerspec);
1223 	if (ret)
1224 		goto err;
1225 
1226 	errno = EINVAL;
1227 	ret = -1;
1228 
1229 	if (timerspec.it_interval.tv_sec || timerspec.it_interval.tv_nsec)
1230 		goto err;
1231 
1232 	if (timerspec.it_value.tv_sec > 1000000)
1233 		goto err;
1234 
1235 	ret = close(timer);
1236 	if (ret)
1237 		return ret;
1238 
1239 	return 0;
1240 
1241 err:
1242 	close(timer);
1243 	return ret;
1244 }
1245 
test_uname(void)1246 int test_uname(void)
1247 {
1248 	struct utsname buf;
1249 	char osrelease[sizeof(buf.release)];
1250 	ssize_t r;
1251 	int fd;
1252 
1253 	memset(&buf.domainname, 'P', sizeof(buf.domainname));
1254 
1255 	if (uname(&buf))
1256 		return 1;
1257 
1258 	if (strncmp("Linux", buf.sysname, sizeof(buf.sysname)))
1259 		return 1;
1260 
1261 	fd = open("/proc/sys/kernel/osrelease", O_RDONLY);
1262 	if (fd == -1)
1263 		return 1;
1264 
1265 	r = read(fd, osrelease, sizeof(osrelease));
1266 	if (r == -1)
1267 		return 1;
1268 
1269 	close(fd);
1270 
1271 	if (osrelease[r - 1] == '\n')
1272 		r--;
1273 
1274 	/* Validate one of the later fields to ensure field sizes are correct */
1275 	if (strncmp(osrelease, buf.release, r))
1276 		return 1;
1277 
1278 	/* Ensure the field domainname is set, it is missing from struct old_utsname */
1279 	if (strnlen(buf.domainname, sizeof(buf.domainname)) == sizeof(buf.domainname))
1280 		return 1;
1281 
1282 	return 0;
1283 }
1284 
test_mmap_munmap(void)1285 int test_mmap_munmap(void)
1286 {
1287 	int ret, fd, i, page_size;
1288 	void *mem;
1289 	size_t file_size, length, mem_length;
1290 	off_t offset, pa_offset;
1291 	struct stat stat_buf;
1292 	const char * const files[] = {
1293 		"/dev/zero",
1294 		"/proc/1/exe", "/proc/self/exe",
1295 		argv0,
1296 		NULL
1297 	};
1298 
1299 	page_size = getpagesize();
1300 	if (page_size < 0)
1301 		return 1;
1302 
1303 	/* find a right file to mmap, existed and accessible */
1304 	for (i = 0; files[i] != NULL; i++) {
1305 		ret = fd = open(files[i], O_RDONLY);
1306 		if (ret == -1)
1307 			continue;
1308 		else
1309 			break;
1310 	}
1311 	if (ret == -1)
1312 		return 1;
1313 
1314 	ret = stat(files[i], &stat_buf);
1315 	if (ret == -1)
1316 		goto end;
1317 
1318 	/* file size of the special /dev/zero is 0, let's assign one manually */
1319 	if (i == 0)
1320 		file_size = 3*page_size;
1321 	else
1322 		file_size = stat_buf.st_size;
1323 
1324 	offset = file_size - 1;
1325 	if (offset < 0)
1326 		offset = 0;
1327 	length = file_size - offset;
1328 	pa_offset = offset & ~(page_size - 1);
1329 	mem_length = length + offset - pa_offset;
1330 
1331 	mem = mmap(NULL, mem_length, PROT_READ, MAP_SHARED, fd, pa_offset);
1332 	if (mem == MAP_FAILED) {
1333 		ret = 1;
1334 		goto end;
1335 	}
1336 
1337 	mem = mremap(mem, mem_length, mem_length * 2, MREMAP_MAYMOVE, 0);
1338 	if (mem == MAP_FAILED) {
1339 		munmap(mem, mem_length);
1340 		ret = 1;
1341 		goto end;
1342 	}
1343 
1344 	ret = munmap(mem, mem_length * 2);
1345 
1346 end:
1347 	close(fd);
1348 	return !!ret;
1349 }
1350 
test_pipe(void)1351 int test_pipe(void)
1352 {
1353 	const char *const msg = "hello, nolibc";
1354 	int pipefd[2];
1355 	char buf[32];
1356 	size_t len;
1357 
1358 	if (pipe(pipefd) == -1)
1359 		return 1;
1360 
1361 	write(pipefd[1], msg, strlen(msg));
1362 	close(pipefd[1]);
1363 	len = read(pipefd[0], buf, sizeof(buf));
1364 	close(pipefd[0]);
1365 
1366 	if (len != strlen(msg))
1367 		return 1;
1368 
1369 	return !!memcmp(buf, msg, len);
1370 }
1371 
test_pwrite_pread(void)1372 int test_pwrite_pread(void)
1373 {
1374 	const off_t offset = (0x12ULL << 32) | 0x34;
1375 	ssize_t ret;
1376 	char buf[2];
1377 	int fd, err;
1378 	off_t offs;
1379 
1380 	fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
1381 	if (fd == -1)
1382 		return __LINE__;
1383 
1384 	/* Write into the middle of the file. */
1385 	ret = pwrite(fd, "abc", 3, offset);
1386 	if (ret != 3) {
1387 		err = __LINE__;
1388 		goto out;
1389 	}
1390 
1391 	/* Make sure the file offset points somewhere else before pread(). */
1392 	offs = lseek(fd, 0, SEEK_END);
1393 	if (offs != offset + 3) {
1394 		err = __LINE__;
1395 		goto out;
1396 	}
1397 
1398 	ret = pread(fd, buf, 2, offset + 1);
1399 	if (ret != 2) {
1400 		err = __LINE__;
1401 		goto out;
1402 	}
1403 
1404 	if (buf[0] != 'b' || buf[1] != 'c') {
1405 		err = __LINE__;
1406 		goto out;
1407 	}
1408 
1409 	err = 0;
1410 
1411 out:
1412 	close(fd);
1413 
1414 	return err;
1415 }
1416 
test_rlimit(void)1417 int test_rlimit(void)
1418 {
1419 	struct rlimit rlim = {
1420 		.rlim_cur = 1 << 20,
1421 		.rlim_max = 1 << 21,
1422 	};
1423 	int ret;
1424 
1425 	ret = setrlimit(RLIMIT_CORE, &rlim);
1426 	if (ret)
1427 		return -1;
1428 
1429 	rlim.rlim_cur = 0;
1430 	rlim.rlim_max = 0;
1431 
1432 	ret = getrlimit(RLIMIT_CORE, &rlim);
1433 	if (ret)
1434 		return -1;
1435 
1436 	if (rlim.rlim_cur != 1 << 20)
1437 		return -1;
1438 	if (rlim.rlim_max != 1 << 21)
1439 		return -1;
1440 
1441 	return 0;
1442 }
1443 
test_openat(void)1444 int test_openat(void)
1445 {
1446 	int dev, null;
1447 
1448 	dev = openat(AT_FDCWD, "/dev", O_DIRECTORY);
1449 	if (dev < 0)
1450 		return -1;
1451 
1452 	null = openat(dev, "null", O_RDONLY);
1453 	close(dev);
1454 	if (null < 0)
1455 		return -1;
1456 
1457 	close(null);
1458 	return 0;
1459 }
1460 
test_open_mode(void)1461 int test_open_mode(void)
1462 {
1463 	const mode_t mode = 0444;
1464 	struct stat stat_buf;
1465 	int fd, ret;
1466 
1467 	fd = open("/tmp", O_TMPFILE | O_RDWR, mode);
1468 	if (fd == -1)
1469 		return -1;
1470 
1471 	ret = fstat(fd, &stat_buf);
1472 	close(fd);
1473 
1474 	if (ret == -1)
1475 		return -1;
1476 
1477 	if ((stat_buf.st_mode & 0777) != mode)
1478 		return -1;
1479 
1480 	return 0;
1481 }
1482 
test_nolibc_enosys(void)1483 int test_nolibc_enosys(void)
1484 {
1485 	if (true)
1486 		return 0;
1487 
1488 #if defined(NOLIBC)
1489 	/*
1490 	 * __nolibc_enosys() will fail the compilation.
1491 	 * Make sure it can be optimized away if not actually called.
1492 	 */
1493 	if (__nolibc_enosys("something") != -ENOSYS)
1494 		return 1;
1495 #endif
1496 
1497 	return 0;
1498 }
1499 
test_namespace(void)1500 int test_namespace(void)
1501 {
1502 	int original_ns, new_ns, ret;
1503 	ino_t original_ns_ino;
1504 	struct stat stat_buf;
1505 
1506 	original_ns = open("/proc/self/ns/uts", O_RDONLY);
1507 	if (original_ns == -1)
1508 		return -1;
1509 
1510 	ret = fstat(original_ns, &stat_buf);
1511 	if (ret)
1512 		goto out;
1513 
1514 	original_ns_ino = stat_buf.st_ino;
1515 
1516 	ret = unshare(CLONE_NEWUTS);
1517 	if (ret)
1518 		goto out;
1519 
1520 	new_ns = open("/proc/self/ns/uts", O_RDONLY);
1521 	if (new_ns == -1) {
1522 		ret = new_ns;
1523 		goto out;
1524 	}
1525 
1526 	ret = fstat(new_ns, &stat_buf);
1527 	close(new_ns);
1528 	if (ret)
1529 		goto out;
1530 
1531 	if (stat_buf.st_ino == original_ns_ino) {
1532 		errno = EINVAL;
1533 		ret = -1;
1534 		goto out;
1535 	}
1536 
1537 	ret = setns(original_ns, CLONE_NEWUTS);
1538 	if (ret)
1539 		goto out;
1540 
1541 	new_ns = open("/proc/self/ns/uts", O_RDONLY);
1542 	if (new_ns == -1) {
1543 		ret = new_ns;
1544 		goto out;
1545 	}
1546 
1547 	ret = fstat(new_ns, &stat_buf);
1548 	if (ret)
1549 		goto out;
1550 
1551 	close(new_ns);
1552 
1553 	if (stat_buf.st_ino != original_ns_ino) {
1554 		errno = EINVAL;
1555 		ret = -1;
1556 		goto out;
1557 	}
1558 
1559 	ret = 0;
1560 
1561 out:
1562 	close(original_ns);
1563 	return ret;
1564 }
1565 
test_large_file(void)1566 int test_large_file(void)
1567 {
1568 	off_t large_seek = ((off_t)UINT32_MAX) + 100;
1569 	int fd, ret, saved_errno;
1570 	ssize_t written;
1571 	off_t off;
1572 
1573 	if (large_seek < UINT32_MAX) {
1574 		errno = EOVERFLOW;
1575 		return -1;
1576 	}
1577 
1578 	fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
1579 	if (fd == -1)
1580 		return -1;
1581 
1582 	off = lseek(fd, large_seek, SEEK_CUR);
1583 	if (off == -1) {
1584 		ret = off;
1585 		goto out;
1586 	} else if (off != large_seek) {
1587 		errno = ERANGE;
1588 		ret = -1;
1589 		goto out;
1590 	}
1591 
1592 	written = write(fd, "1", 1);
1593 	if (written == -1) {
1594 		ret = written;
1595 		goto out;
1596 	}
1597 
1598 	ret = 0;
1599 out:
1600 	saved_errno = errno;
1601 	close(fd);
1602 	errno = saved_errno;
1603 	return ret;
1604 }
1605 
test_sendfile(void)1606 int test_sendfile(void)
1607 {
1608 	char data_in[] = "This is some data";
1609 	const size_t data_sz = sizeof(data_in);
1610 	char data_out[data_sz + 10];
1611 	int in_fd, out_fd;
1612 	int ret;
1613 
1614 	/* Create two tmp files */
1615 	in_fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
1616 	out_fd = open("/tmp", O_TMPFILE | O_RDWR, 0644);
1617 
1618 	if (in_fd == -1 || out_fd == -1) {
1619 		ret = __LINE__;
1620 		goto out;
1621 	}
1622 
1623 	/* Populate the "in" file */
1624 	ret = write(in_fd, data_in, data_sz);
1625 	if (ret != data_sz) {
1626 		ret = __LINE__;
1627 		goto out;
1628 	}
1629 
1630 	/* Rewind the "in" file */
1631 	if (lseek(in_fd, 0, SEEK_SET)) {
1632 		ret = __LINE__;
1633 		goto out;
1634 	}
1635 
1636 	/* Use sendfile() to copy "in" to "out" */
1637 	ret = sendfile(out_fd, in_fd, NULL, data_sz + 5);
1638 	if (ret != data_sz) {
1639 		ret = __LINE__;
1640 		goto out;
1641 	}
1642 
1643 	/* Rewind the "out" file */
1644 	if (lseek(out_fd, 0, SEEK_SET)) {
1645 		ret = __LINE__;
1646 		goto out;
1647 	}
1648 
1649 	/* Read back the transferred data */
1650 	ret = read(out_fd, data_out, sizeof(data_out));
1651 	if (ret != data_sz) {
1652 		ret = __LINE__;
1653 		goto out;
1654 	}
1655 
1656 	/* Check we have the same data in both files */
1657 	if (memcmp(data_out, data_in, data_sz)) {
1658 		ret = __LINE__;
1659 		goto out;
1660 	}
1661 
1662 	/* Test passed */
1663 	ret = 0;
1664 
1665 out:
1666 	close(out_fd);
1667 	close(in_fd);
1668 
1669 	return ret;
1670 }
1671 
1672 /* Run syscall tests between IDs <min> and <max>.
1673  * Return 0 on success, non-zero on failure.
1674  */
run_syscall(int min,int max)1675 int run_syscall(int min, int max)
1676 {
1677 	struct timeval tv;
1678 	struct timezone tz;
1679 	struct timespec ts;
1680 	struct stat stat_buf;
1681 	int euid0;
1682 	int proc;
1683 	int test;
1684 	int tmp;
1685 	struct iovec iov_one = {
1686 		.iov_base = &tmp,
1687 		.iov_len = 1,
1688 	};
1689 	int ret = 0;
1690 	void *p1, *p2;
1691 	int has_gettid = 1;
1692 	int has_brk;
1693 	int has_working_64bit_syscall_arg = 1;
1694 
1695 	/* <proc> indicates whether or not /proc is mounted */
1696 	proc = stat("/proc", &stat_buf) == 0;
1697 
1698 	/* this will be used to skip certain tests that can't be run unprivileged */
1699 	euid0 = geteuid() == 0;
1700 
1701 	/* from 2.30, glibc provides gettid() */
1702 #if defined(__GLIBC_MINOR__) && defined(__GLIBC__)
1703 	has_gettid = __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 30);
1704 #endif
1705 
1706 	/* on musl setting brk()/sbrk() always fails */
1707 	has_brk = brk(0) == 0;
1708 
1709 #if defined(__mips__) && defined(_ABIN32)
1710 	/* https://lore.kernel.org/qemu-devel/fed03914-a95a-4522-a432-f129264cb2ac@t-8ch.de/ */
1711 	has_working_64bit_syscall_arg = getpid() == 1;
1712 #endif
1713 
1714 	for (test = min; test >= 0 && test <= max; test++) {
1715 		int llen = 0; /* line length */
1716 
1717 		/* avoid leaving empty lines below, this will insert holes into
1718 		 * test numbers.
1719 		 */
1720 		switch (test + __LINE__ + 1) {
1721 		CASE_TEST(access);            EXPECT_SYSZR(proc, access("/proc/self", R_OK)); break;
1722 		CASE_TEST(access_bad);        EXPECT_SYSER(proc, access("/proc/self", W_OK), -1, EPERM); break;
1723 		CASE_TEST(clock_getres);      EXPECT_SYSZR(1, clock_getres(CLOCK_MONOTONIC, &ts)); break;
1724 		CASE_TEST(clock_gettime);     EXPECT_SYSZR(1, clock_gettime(CLOCK_MONOTONIC, &ts)); break;
1725 		CASE_TEST(clock_settime);     EXPECT_SYSER(1, clock_settime(CLOCK_MONOTONIC, &ts), -1, EINVAL); break;
1726 		CASE_TEST(getcwd);            EXPECT_SYSZR(proc, test_getcwd()); break;
1727 		CASE_TEST(getpid);            EXPECT_SYSNE(1, getpid(), -1); break;
1728 		CASE_TEST(getppid);           EXPECT_SYSNE(1, getppid(), -1); break;
1729 		CASE_TEST(gettid);            EXPECT_SYSNE(has_gettid, gettid(), -1); break;
1730 		CASE_TEST(getpgid_self);      EXPECT_SYSNE(1, getpgid(0), -1); break;
1731 		CASE_TEST(getpgid_bad);       EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break;
1732 		CASE_TEST(kill_0);            EXPECT_SYSZR(1, kill(getpid(), 0)); break;
1733 		CASE_TEST(kill_CONT);         EXPECT_SYSZR(1, kill(getpid(), 0)); break;
1734 		CASE_TEST(kill_BADPID);       EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break;
1735 		CASE_TEST(sbrk_0);            EXPECT_PTRNE(has_brk, sbrk(0), (void *)-1); break;
1736 		CASE_TEST(sbrk);              if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(has_brk, (p2 == (void *)-1) || p2 == p1); break;
1737 		CASE_TEST(brk);               EXPECT_SYSZR(has_brk, brk(sbrk(0))); break;
1738 		CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); chdir(getenv("PWD")); break;
1739 		CASE_TEST(chdir_dot);         EXPECT_SYSZR(1, chdir(".")); break;
1740 		CASE_TEST(chdir_blah);        EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;
1741 		CASE_TEST(chmod_argv0);       EXPECT_SYSZR(1, chmod(argv0, 0555)); break;
1742 		CASE_TEST(chmod_self);        EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;
1743 		CASE_TEST(chown_self);        EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
1744 		CASE_TEST(chroot_root);       EXPECT_SYSZR(euid0, chroot("/")); break;
1745 		CASE_TEST(chroot_blah);       EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
1746 		CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(argv0), -1, ENOTDIR); break;
1747 		CASE_TEST(clock_nanosleep);   ts.tv_nsec = -1; EXPECT_EQ(1, EINVAL, clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL)); break;
1748 		CASE_TEST(close_m1);          EXPECT_SYSER(1, close(-1), -1, EBADF); break;
1749 		CASE_TEST(close_dup);         EXPECT_SYSZR(1, close(dup(0))); break;
1750 		CASE_TEST(dup_0);             tmp = dup(0);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
1751 		CASE_TEST(dup_m1);            tmp = dup(-1); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
1752 		CASE_TEST(dup2_0);            tmp = dup2(0, 100);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
1753 		CASE_TEST(dup2_m1);           tmp = dup2(-1, 100); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
1754 		CASE_TEST(dup3_0);            tmp = dup3(0, 100, 0);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
1755 		CASE_TEST(dup3_m1);           tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
1756 		CASE_TEST(execve_root);       EXPECT_SYSER(1, execve("/", (char*[]){ [0] = (char []){"/"}, [1] = NULL }, NULL), -1, EACCES); break;
1757 		CASE_TEST(fchdir_stdin);      EXPECT_SYSER(1, fchdir(STDIN_FILENO), -1, ENOTDIR); break;
1758 		CASE_TEST(fchdir_badfd);      EXPECT_SYSER(1, fchdir(-1), -1, EBADF); break;
1759 		CASE_TEST(fdopendir_notdir);  EXPECT_SYSER(1, (uintptr_t)fdopendir(STDIN_FILENO), (uintptr_t)NULL, ENOTDIR); break;
1760 		CASE_TEST(file_stream);       EXPECT_SYSZR(1, test_file_stream()); break;
1761 		CASE_TEST(file_stream_wsr);   EXPECT_SYSZR(1, test_file_stream_wsr()); break;
1762 		CASE_TEST(fork);              EXPECT_SYSZR(1, test_fork(FORK_STANDARD)); break;
1763 		CASE_TEST(ftruncate);         EXPECT_SYSZR(1, test_ftruncate()); break;
1764 		CASE_TEST(getdents64_root);   EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
1765 		CASE_TEST(getdents64_null);   EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
1766 		CASE_TEST(directories);       EXPECT_SYSZR(is_nolibc && proc, test_dirent()); break;
1767 		CASE_TEST(getrandom);         EXPECT_SYSZR(1, test_getrandom()); break;
1768 		CASE_TEST(gettimeofday_tv);   EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break;
1769 		CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break;
1770 		CASE_TEST(getpagesize);       EXPECT_SYSZR(1, test_getpagesize()); break;
1771 		CASE_TEST(ioctl_tiocinq);     EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;
1772 		CASE_TEST(link_root1);        EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;
1773 		CASE_TEST(link_blah);         EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break;
1774 		CASE_TEST(link_dir);          EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break;
1775 		CASE_TEST(link_cross);        EXPECT_SYSER(proc, link("/proc/self/cmdline", "/blah"), -1, EXDEV); break;
1776 		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
1777 		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
1778 		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
1779 		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;
1780 		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap(NULL, 0), -1, EINVAL); break;
1781 		CASE_TEST(mmap_munmap_good);  EXPECT_SYSZR(1, test_mmap_munmap()); break;
1782 		CASE_TEST(nanosleep);         ts.tv_nsec = -1; EXPECT_SYSER(1, nanosleep(&ts, NULL), -1, EINVAL); break;
1783 		CASE_TEST(nolibc_enosys);     EXPECT_ZR(is_nolibc, test_nolibc_enosys()); break;
1784 		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", O_RDONLY), -1); if (tmp != -1) close(tmp); break;
1785 		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", O_RDONLY), -1, ENOENT); if (tmp != -1) close(tmp); break;
1786 		CASE_TEST(openat_dir);        EXPECT_SYSZR(1, test_openat()); break;
1787 		CASE_TEST(open_mode);         EXPECT_SYSZR(1, test_open_mode()); break;
1788 		CASE_TEST(opendir_notdir);    EXPECT_SYSER(1, (uintptr_t)opendir("/dev/null"), (uintptr_t)NULL, ENOTDIR); break;
1789 		CASE_TEST(pipe);              EXPECT_SYSZR(1, test_pipe()); break;
1790 		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;
1791 		CASE_TEST(poll_stdout);       EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;
1792 		CASE_TEST(poll_fault);        EXPECT_SYSER(1, poll(NULL, 1, 0), -1, EFAULT); break;
1793 		CASE_TEST(prctl);             EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;
1794 		CASE_TEST(pwrite_pread);      EXPECT_SYSZR(has_working_64bit_syscall_arg, test_pwrite_pread()); break;
1795 		CASE_TEST(read_badf);         EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;
1796 		CASE_TEST(rlimit);            EXPECT_SYSZR(1, test_rlimit()); break;
1797 		CASE_TEST(rmdir_blah);        EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break;
1798 		CASE_TEST(sched_yield);       EXPECT_SYSZR(1, sched_yield()); break;
1799 		CASE_TEST(select_null);       EXPECT_SYSZR(1, ({ struct timeval tv = { 0 }; select(0, NULL, NULL, NULL, &tv); })); break;
1800 		CASE_TEST(select_stdout);     EXPECT_SYSNE(1, ({ fd_set fds; FD_ZERO(&fds); FD_SET(1, &fds); select(2, NULL, &fds, NULL, NULL); }), -1); break;
1801 		CASE_TEST(select_fault);      EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;
1802 		CASE_TEST(sendfile);          EXPECT_SYSZR(1, test_sendfile()); break;
1803 		CASE_TEST(stat_blah);         EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;
1804 		CASE_TEST(stat_fault);        EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
1805 		CASE_TEST(stat_rdev);         EXPECT_SYSZR(1, ({ int ret = stat("/dev/null", &stat_buf); ret ?: stat_buf.st_rdev != makedev(1, 3); })); break;
1806 		CASE_TEST(stat_timestamps);   EXPECT_SYSZR(1, test_stat_timestamps()); break;
1807 		CASE_TEST(symlink_root);      EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
1808 		CASE_TEST(timer);             EXPECT_SYSZR(1, test_timer()); break;
1809 		CASE_TEST(timerfd);           EXPECT_SYSZR(1, test_timerfd()); break;
1810 		CASE_TEST(uname);             EXPECT_SYSZR(proc, test_uname()); break;
1811 		CASE_TEST(uname_fault);       EXPECT_SYSER(1, uname(NULL), -1, EFAULT); break;
1812 		CASE_TEST(unlink_root);       EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
1813 		CASE_TEST(unlink_blah);       EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break;
1814 		CASE_TEST(vfork);             EXPECT_SYSZR(1, test_fork(FORK_VFORK)); break;
1815 		CASE_TEST(wait_child);        EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break;
1816 		CASE_TEST(waitpid_min);       EXPECT_SYSER(1, waitpid(INT_MIN, &tmp, WNOHANG), -1, ESRCH); break;
1817 		CASE_TEST(waitpid_child);     EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;
1818 		CASE_TEST(write_badf);        EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;
1819 		CASE_TEST(write_zero);        EXPECT_SYSZR(1, write(1, &tmp, 0)); break;
1820 		CASE_TEST(readv_badf);        EXPECT_SYSER(1, readv(-1, &iov_one, 1), -1, EBADF); break;
1821 		CASE_TEST(readv_zero);        EXPECT_SYSZR(1, readv(0, NULL, 0)); break;
1822 		CASE_TEST(writev_badf);       EXPECT_SYSER(1, writev(-1, &iov_one, 1), -1, EBADF); break;
1823 		CASE_TEST(writev_zero);       EXPECT_SYSZR(1, writev(1, NULL, 0)); break;
1824 		CASE_TEST(ptrace);            tmp = ptrace(PTRACE_CONT, getpid(), NULL, NULL); EXPECT_SYSER(tmp != -1 && errno != ENOSYS, tmp, -1, EFAULT); break;
1825 		CASE_TEST(syscall_noargs);    EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break;
1826 		CASE_TEST(syscall_args);      EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break;
1827 		CASE_TEST(_syscall_noargs);   EXPECT_SYSEQ(is_nolibc, _syscall(__NR_getpid), getpid()); break;
1828 		CASE_TEST(_syscall_args);     EXPECT_SYSEQ(is_nolibc, _syscall(__NR_statx, 0, NULL, 0, 0, NULL), -EFAULT); break;
1829 		CASE_TEST(namespace);         EXPECT_SYSZR(euid0 && proc, test_namespace()); break;
1830 		CASE_TEST(largefile);         EXPECT_SYSZR(has_working_64bit_syscall_arg, test_large_file()); break;
1831 		case __LINE__:
1832 			return ret; /* must be last */
1833 		/* note: do not set any defaults so as to permit holes above */
1834 		}
1835 	}
1836 	return ret;
1837 }
1838 
test_alloca(void)1839 int test_alloca(void)
1840 {
1841 	uint64_t *x;
1842 
1843 	x = alloca(sizeof(*x));
1844 
1845 	*x = 0x1234;
1846 	__asm__ ("" : "+r" (x));
1847 
1848 	return *x - 0x1234;
1849 }
1850 
test_difftime(void)1851 int test_difftime(void)
1852 {
1853 	if (difftime(200., 100.) != 100.)
1854 		return 1;
1855 
1856 	if (difftime(100., 200.) != -100.)
1857 		return 1;
1858 
1859 	return 0;
1860 }
1861 
test_time_types(void)1862 int test_time_types(void)
1863 {
1864 #ifdef NOLIBC
1865 	struct __kernel_timespec kts;
1866 	struct timespec ts;
1867 
1868 	if (!__builtin_types_compatible_p(time_t, __kernel_time64_t))
1869 		return 1;
1870 
1871 	if (sizeof(ts) != sizeof(kts))
1872 		return 1;
1873 
1874 	if (!__builtin_types_compatible_p(__typeof__(ts.tv_sec), __typeof__(kts.tv_sec)))
1875 		return 1;
1876 
1877 	if (!__builtin_types_compatible_p(__typeof__(ts.tv_nsec), __typeof__(kts.tv_nsec)))
1878 		return 1;
1879 
1880 	if (offsetof(__typeof__(ts), tv_sec) != offsetof(__typeof__(kts), tv_sec))
1881 		return 1;
1882 
1883 	if (offsetof(__typeof__(ts), tv_nsec) != offsetof(__typeof__(kts), tv_nsec))
1884 		return 1;
1885 #endif /* NOLIBC */
1886 
1887 	return 0;
1888 }
1889 
test_fd_set(void)1890 int test_fd_set(void)
1891 {
1892 	fd_set set, clr;
1893 	int fd, i;
1894 
1895 	/* FD_SET() and FD_CLR() must change exactly one fd */
1896 	for (fd = 0; fd < FD_SETSIZE; fd++) {
1897 		FD_ZERO(&set);
1898 		FD_SET(fd, &set);
1899 		memset(&clr, 0xff, sizeof(clr));
1900 		FD_CLR(fd, &clr);
1901 		for (i = 0; i < FD_SETSIZE; i++)
1902 			if (!!FD_ISSET(i, &set) != (i == fd) ||
1903 			    !!FD_ISSET(i, &clr) != (i != fd))
1904 				return 1;
1905 	}
1906 
1907 	return 0;
1908 }
1909 
test_malloc(void)1910 int test_malloc(void)
1911 {
1912 	size_t sz_array1, sz_array2, sz_array3;
1913 	int *array1, *array2, *array3;
1914 	int pagesize = getpagesize();
1915 	size_t idx;
1916 
1917 	if (pagesize < 0)
1918 		return 1;
1919 
1920 	/* Dependent on the page size, as that is the granularity of our allocator. */
1921 	sz_array1 = pagesize / 2;
1922 	array1 = malloc(sz_array1 * sizeof(*array1));
1923 	if (!array1)
1924 		return 2;
1925 
1926 	for (idx = 0; idx < sz_array1; idx++)
1927 		array1[idx] = idx;
1928 
1929 	sz_array2 = pagesize * 2;
1930 	array2 = calloc(sz_array2, sizeof(*array2));
1931 	if (!array2) {
1932 		free(array1);
1933 		return 3;
1934 	}
1935 
1936 	for (idx = 0; idx < sz_array2; idx++) {
1937 		if (array2[idx] != 0) {
1938 			free(array2);
1939 			return 4;
1940 		}
1941 		array2[idx] = idx + sz_array1;
1942 	}
1943 
1944 	/* Resize array1 into array3 and append array2 at the end. */
1945 	sz_array3 = sz_array1 + sz_array2;
1946 	array3 = realloc(array1, sz_array3 * sizeof(*array3));
1947 	if (!array3) {
1948 		free(array2);
1949 		free(array1);
1950 		return 5;
1951 	}
1952 	memcpy(array3 + sz_array1, array2, sizeof(*array2) * sz_array2);
1953 	free(array2);
1954 
1955 	/* The contents must be contiguous now. */
1956 	for (idx = 0; idx < sz_array3; idx++)
1957 		if (array3[idx] != (int)idx)
1958 			return 6;
1959 
1960 	free(array3);
1961 	return 0;
1962 }
1963 
run_stdlib(int min,int max)1964 int run_stdlib(int min, int max)
1965 {
1966 	int test;
1967 	int ret = 0;
1968 
1969 	for (test = min; test >= 0 && test <= max; test++) {
1970 		int llen = 0; /* line length */
1971 
1972 		/* For functions that take a long buffer, like strlcat()
1973 		 * Add some more chars after the \0, to test functions that overwrite the buffer set
1974 		 * the \0 at the exact right position.
1975 		 */
1976 		char buf[11] = "test123456";
1977 		buf[4] = '\0';
1978 
1979 
1980 		/* avoid leaving empty lines below, this will insert holes into
1981 		 * test numbers.
1982 		 */
1983 		switch (test + __LINE__ + 1) {
1984 		CASE_TEST(getenv_TERM);        EXPECT_STRNZ(1, getenv("TERM")); break;
1985 		CASE_TEST(getenv_blah);        EXPECT_STRZR(1, getenv("blah")); break;
1986 		CASE_TEST(setcmp_blah_blah);   EXPECT_EQ(1, strcmp("blah", "blah"), 0); break;
1987 		CASE_TEST(setcmp_blah_blah2);  EXPECT_NE(1, strcmp("blah", "blah2"), 0); break;
1988 		CASE_TEST(setncmp_blah_blah);  EXPECT_EQ(1, strncmp("blah", "blah", 10), 0); break;
1989 		CASE_TEST(setncmp_blah_blah4); EXPECT_EQ(1, strncmp("blah", "blah4", 4), 0); break;
1990 		CASE_TEST(setncmp_blah_blah5); EXPECT_NE(1, strncmp("blah", "blah5", 5), 0); break;
1991 		CASE_TEST(setncmp_blah_blah6); EXPECT_NE(1, strncmp("blah", "blah6", 6), 0); break;
1992 		CASE_TEST(strchr_foobar_o);    EXPECT_STREQ(1, strchr("foobar", 'o'), "oobar"); break;
1993 		CASE_TEST(strchr_foobar_z);    EXPECT_STRZR(1, strchr("foobar", 'z')); break;
1994 		CASE_TEST(strrchr_foobar_o);   EXPECT_STREQ(1, strrchr("foobar", 'o'), "obar"); break;
1995 		CASE_TEST(strrchr_foobar_z);   EXPECT_STRZR(1, strrchr("foobar", 'z')); break;
1996 		CASE_TEST(strlcat_0);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 0), buf, 3, "test"); break;
1997 		CASE_TEST(strlcat_1);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 1), buf, 4, "test"); break;
1998 		CASE_TEST(strlcat_5);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 5), buf, 7, "test"); break;
1999 		CASE_TEST(strlcat_6);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 6), buf, 7, "testb"); break;
2000 		CASE_TEST(strlcat_7);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 7), buf, 7, "testba"); break;
2001 		CASE_TEST(strlcat_8);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 8), buf, 7, "testbar"); break;
2002 		CASE_TEST(strlcpy_0);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 0), buf, 3, "test"); break;
2003 		CASE_TEST(strlcpy_1);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 1), buf, 3, ""); break;
2004 		CASE_TEST(strlcpy_2);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 2), buf, 3, "b"); break;
2005 		CASE_TEST(strlcpy_3);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 3), buf, 3, "ba"); break;
2006 		CASE_TEST(strlcpy_4);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 4), buf, 3, "bar"); break;
2007 		CASE_TEST(strstr_foobar_foo);  EXPECT_STREQ(1, strstr("foobar", "foo"), "foobar"); break;
2008 		CASE_TEST(strstr_foobar_bar);  EXPECT_STREQ(1, strstr("foobar", "bar"), "bar"); break;
2009 		CASE_TEST(strstr_foobar_baz);  EXPECT_PTREQ(1, strstr("foobar", "baz"), NULL); break;
2010 		CASE_TEST(memcmp_20_20);       EXPECT_EQ(1, memcmp("aaa\x20", "aaa\x20", 4), 0); break;
2011 		CASE_TEST(memcmp_20_60);       EXPECT_LT(1, memcmp("aaa\x20", "aaa\x60", 4), 0); break;
2012 		CASE_TEST(memcmp_60_20);       EXPECT_GT(1, memcmp("aaa\x60", "aaa\x20", 4), 0); break;
2013 		CASE_TEST(memcmp_20_e0);       EXPECT_LT(1, memcmp("aaa\x20", "aaa\xe0", 4), 0); break;
2014 		CASE_TEST(memcmp_e0_20);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x20", 4), 0); break;
2015 		CASE_TEST(memcmp_80_e0);       EXPECT_LT(1, memcmp("aaa\x80", "aaa\xe0", 4), 0); break;
2016 		CASE_TEST(memcmp_e0_80);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x80", 4), 0); break;
2017 		CASE_TEST(limit_int8_max);          EXPECT_EQ(1, INT8_MAX,         (int8_t)          0x7f); break;
2018 		CASE_TEST(limit_int8_min);          EXPECT_EQ(1, INT8_MIN,         (int8_t)          0x80); break;
2019 		CASE_TEST(limit_uint8_max);         EXPECT_EQ(1, UINT8_MAX,        (uint8_t)         0xff); break;
2020 		CASE_TEST(limit_int16_max);         EXPECT_EQ(1, INT16_MAX,        (int16_t)         0x7fff); break;
2021 		CASE_TEST(limit_int16_min);         EXPECT_EQ(1, INT16_MIN,        (int16_t)         0x8000); break;
2022 		CASE_TEST(limit_uint16_max);        EXPECT_EQ(1, UINT16_MAX,       (uint16_t)        0xffff); break;
2023 		CASE_TEST(limit_int32_max);         EXPECT_EQ(1, INT32_MAX,        (int32_t)         0x7fffffff); break;
2024 		CASE_TEST(limit_int32_min);         EXPECT_EQ(1, INT32_MIN,        (int32_t)         0x80000000); break;
2025 		CASE_TEST(limit_uint32_max);        EXPECT_EQ(1, UINT32_MAX,       (uint32_t)        0xffffffff); break;
2026 		CASE_TEST(limit_int64_max);         EXPECT_EQ(1, INT64_MAX,        (int64_t)         0x7fffffffffffffff); break;
2027 		CASE_TEST(limit_int64_min);         EXPECT_EQ(1, INT64_MIN,        (int64_t)         0x8000000000000000); break;
2028 		CASE_TEST(limit_uint64_max);        EXPECT_EQ(1, UINT64_MAX,       (uint64_t)        0xffffffffffffffff); break;
2029 		CASE_TEST(limit_int_least8_max);    EXPECT_EQ(1, INT_LEAST8_MAX,   (int_least8_t)    0x7f); break;
2030 		CASE_TEST(limit_int_least8_min);    EXPECT_EQ(1, INT_LEAST8_MIN,   (int_least8_t)    0x80); break;
2031 		CASE_TEST(limit_uint_least8_max);   EXPECT_EQ(1, UINT_LEAST8_MAX,  (uint_least8_t)   0xff); break;
2032 		CASE_TEST(limit_int_least16_max);   EXPECT_EQ(1, INT_LEAST16_MAX,  (int_least16_t)   0x7fff); break;
2033 		CASE_TEST(limit_int_least16_min);   EXPECT_EQ(1, INT_LEAST16_MIN,  (int_least16_t)   0x8000); break;
2034 		CASE_TEST(limit_uint_least16_max);  EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t)  0xffff); break;
2035 		CASE_TEST(limit_int_least32_max);   EXPECT_EQ(1, INT_LEAST32_MAX,  (int_least32_t)   0x7fffffff); break;
2036 		CASE_TEST(limit_int_least32_min);   EXPECT_EQ(1, INT_LEAST32_MIN,  (int_least32_t)   0x80000000); break;
2037 		CASE_TEST(limit_uint_least32_max);  EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t)  0xffffffffU); break;
2038 		CASE_TEST(limit_int_least64_min);   EXPECT_EQ(1, INT_LEAST64_MIN,  (int_least64_t)   0x8000000000000000LL); break;
2039 		CASE_TEST(limit_int_least64_max);   EXPECT_EQ(1, INT_LEAST64_MAX,  (int_least64_t)   0x7fffffffffffffffLL); break;
2040 		CASE_TEST(limit_uint_least64_max);  EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t)  0xffffffffffffffffULL); break;
2041 		CASE_TEST(limit_int_fast8_max);     EXPECT_EQ(1, INT_FAST8_MAX,    (int_fast8_t)     0x7f); break;
2042 		CASE_TEST(limit_int_fast8_min);     EXPECT_EQ(1, INT_FAST8_MIN,    (int_fast8_t)     0x80); break;
2043 		CASE_TEST(limit_uint_fast8_max);    EXPECT_EQ(1, UINT_FAST8_MAX,   (uint_fast8_t)    0xff); break;
2044 		CASE_TEST(limit_int_fast16_min);    EXPECT_EQ(1, INT_FAST16_MIN,   (int_fast16_t)    SINT_MIN_OF_TYPE(int_fast16_t)); break;
2045 		CASE_TEST(limit_int_fast16_max);    EXPECT_EQ(1, INT_FAST16_MAX,   (int_fast16_t)    SINT_MAX_OF_TYPE(int_fast16_t)); break;
2046 		CASE_TEST(limit_uint_fast16_max);   EXPECT_EQ(1, UINT_FAST16_MAX,  (uint_fast16_t)   UINTPTR_MAX); break;
2047 		CASE_TEST(limit_int_fast32_min);    EXPECT_EQ(1, INT_FAST32_MIN,   (int_fast32_t)    SINT_MIN_OF_TYPE(int_fast32_t)); break;
2048 		CASE_TEST(limit_int_fast32_max);    EXPECT_EQ(1, INT_FAST32_MAX,   (int_fast32_t)    SINT_MAX_OF_TYPE(int_fast32_t)); break;
2049 		CASE_TEST(limit_uint_fast32_max);   EXPECT_EQ(1, UINT_FAST32_MAX,  (uint_fast32_t)   UINTPTR_MAX); break;
2050 		CASE_TEST(limit_int_fast64_min);    EXPECT_EQ(1, INT_FAST64_MIN,   (int_fast64_t)    INT64_MIN); break;
2051 		CASE_TEST(limit_int_fast64_max);    EXPECT_EQ(1, INT_FAST64_MAX,   (int_fast64_t)    INT64_MAX); break;
2052 		CASE_TEST(limit_uint_fast64_max);   EXPECT_EQ(1, UINT_FAST64_MAX,  (uint_fast64_t)   UINT64_MAX); break;
2053 		CASE_TEST(sizeof_long_sane);        EXPECT_EQ(1, sizeof(long) == 8 || sizeof(long) == 4, 1); break;
2054 		CASE_TEST(limit_intptr_min);        EXPECT_EQ(1, INTPTR_MIN,  sizeof(long) == 8 ? (intptr_t)  0x8000000000000000LL  : (intptr_t)  0x80000000); break;
2055 		CASE_TEST(limit_intptr_max);        EXPECT_EQ(1, INTPTR_MAX,  sizeof(long) == 8 ? (intptr_t)  0x7fffffffffffffffLL  : (intptr_t)  0x7fffffff); break;
2056 		CASE_TEST(limit_uintptr_max);       EXPECT_EQ(1, UINTPTR_MAX, sizeof(long) == 8 ? (uintptr_t) 0xffffffffffffffffULL : (uintptr_t) 0xffffffffU); break;
2057 		CASE_TEST(limit_ptrdiff_min);       EXPECT_EQ(1, PTRDIFF_MIN, sizeof(long) == 8 ? (ptrdiff_t) 0x8000000000000000LL  : (ptrdiff_t) 0x80000000); break;
2058 		CASE_TEST(limit_ptrdiff_max);       EXPECT_EQ(1, PTRDIFF_MAX, sizeof(long) == 8 ? (ptrdiff_t) 0x7fffffffffffffffLL  : (ptrdiff_t) 0x7fffffff); break;
2059 		CASE_TEST(limit_size_max);          EXPECT_EQ(1, SIZE_MAX,    sizeof(long) == 8 ? (size_t)    0xffffffffffffffffULL : (size_t)    0xffffffffU); break;
2060 		CASE_TEST(strtol_simple);           EXPECT_STRTOX(1, strtol, "35", 10, 35, -1, 0); break;
2061 		CASE_TEST(strtol_positive);         EXPECT_STRTOX(1, strtol, "+35", 10, 35, -1, 0); break;
2062 		CASE_TEST(strtol_negative);         EXPECT_STRTOX(1, strtol, "-35", 10, -35, -1, 0); break;
2063 		CASE_TEST(strtol_hex_auto);         EXPECT_STRTOX(1, strtol, "0xFF", 0, 255, -1, 0); break;
2064 		CASE_TEST(strtol_base36);           EXPECT_STRTOX(1, strtol, "12yZ", 36, 50507, -1, 0); break;
2065 		CASE_TEST(strtol_cutoff);           EXPECT_STRTOX(1, strtol, "1234567890", 8, 342391, 7, 0); break;
2066 		CASE_TEST(strtol_octal_auto);       EXPECT_STRTOX(1, strtol, "011", 0, 9, -1, 0); break;
2067 		CASE_TEST(strtol_hex_00);           EXPECT_STRTOX(1, strtol, "0x00", 16, 0, -1, 0); break;
2068 		CASE_TEST(strtol_hex_FF);           EXPECT_STRTOX(1, strtol, "FF", 16, 255, -1, 0); break;
2069 		CASE_TEST(strtol_hex_ff);           EXPECT_STRTOX(1, strtol, "ff", 16, 255, -1, 0); break;
2070 		CASE_TEST(strtol_hex_prefix);       EXPECT_STRTOX(1, strtol, "0xFF", 16, 255, -1, 0); break;
2071 		CASE_TEST(strtol_trailer);          EXPECT_STRTOX(1, strtol, "35foo", 10, 35, 2, 0); break;
2072 		CASE_TEST(strtol_overflow);         EXPECT_STRTOX(1, strtol, "0x8000000000000000", 16, LONG_MAX, -1, ERANGE); break;
2073 		CASE_TEST(strtol_underflow);        EXPECT_STRTOX(1, strtol, "-0x8000000000000001", 16, LONG_MIN, -1, ERANGE); break;
2074 		CASE_TEST(strtoul_negative);        EXPECT_STRTOX(1, strtoul, "-0x1", 16, ULONG_MAX, 4, 0); break;
2075 		CASE_TEST(strtoul_overflow);        EXPECT_STRTOX(1, strtoul, "0x10000000000000000", 16, ULONG_MAX, -1, ERANGE); break;
2076 		CASE_TEST(strerror_success);        EXPECT_STREQ(is_nolibc, strerror(0), "errno=0"); break;
2077 		CASE_TEST(strerror_EINVAL);         EXPECT_STREQ(is_nolibc, strerror(EINVAL), "errno=22"); break;
2078 		CASE_TEST(strerror_int_max);        EXPECT_STREQ(is_nolibc, strerror(INT_MAX), "errno=2147483647"); break;
2079 		CASE_TEST(strerror_int_min);        EXPECT_STREQ(is_nolibc, strerror(INT_MIN), "errno=-2147483648"); break;
2080 		CASE_TEST(tolower);                 EXPECT_EQ(1, tolower('A'), 'a'); break;
2081 		CASE_TEST(tolower_noop);            EXPECT_EQ(1, tolower('a'), 'a'); break;
2082 		CASE_TEST(toupper);                 EXPECT_EQ(1, toupper('a'), 'A'); break;
2083 		CASE_TEST(toupper_noop);            EXPECT_EQ(1, toupper('A'), 'A'); break;
2084 		CASE_TEST(abs);                     EXPECT_EQ(1, abs(-10), 10); break;
2085 		CASE_TEST(abs_noop);                EXPECT_EQ(1, abs(10), 10); break;
2086 		CASE_TEST(alloca);                  EXPECT_ZR(1, test_alloca()); break;
2087 		CASE_TEST(difftime);                EXPECT_ZR(1, test_difftime()); break;
2088 		CASE_TEST(memchr_foobar6_o);        EXPECT_STREQ(1, memchr("foobar", 'o', 6), "oobar"); break;
2089 		CASE_TEST(memchr_foobar3_b);        EXPECT_STRZR(1, memchr("foobar", 'b', 3)); break;
2090 		CASE_TEST(time_types);              EXPECT_ZR(is_nolibc, test_time_types()); break;
2091 		CASE_TEST(fd_set);                  EXPECT_ZR(1, test_fd_set()); break;
2092 		CASE_TEST(makedev);                 EXPECT_EQ(1, makedev(0x12, 0x34), 0x1234); break;
2093 		CASE_TEST(major);                   EXPECT_EQ(1, major(0x1234), 0x12); break;
2094 		CASE_TEST(minor);                   EXPECT_EQ(1, minor(0x1234), 0x34); break;
2095 		CASE_TEST(makedev_big);             EXPECT_EQ(1, makedev(0x11223344, 0x55667788), 0x1122355667734488); break;
2096 		CASE_TEST(major_big);               EXPECT_EQ(1, major(0x1122355667734488), 0x11223344); break;
2097 		CASE_TEST(minor_big);               EXPECT_EQ(1, minor(0x1122355667734488), 0x55667788); break;
2098 		CASE_TEST(malloc);                  EXPECT_ZR(1, test_malloc()); break;
2099 		CASE_TEST(bswap_16);                EXPECT_EQ(1, bswap_16(0x0123), 0x2301); break;
2100 		CASE_TEST(bswap_32);                EXPECT_EQ(1, bswap_32(0x01234567), 0x67452301); break;
2101 		CASE_TEST(bswap_64);                EXPECT_EQ(1, bswap_64(0x0123456789abcdef), 0xefcdab8967452301); break;
2102 		CASE_TEST(htobe16);                 EXPECT_EQ(1, htobe16(is_le ? 0x0123 : 0x2301), 0x2301); break;
2103 		CASE_TEST(htole16);                 EXPECT_EQ(1, htole16(is_le ? 0x0123 : 0x2301), 0x0123); break;
2104 		CASE_TEST(htobe32);                 EXPECT_EQ(1, htobe32(is_le ? 0x01234567 : 0x67452301), 0x67452301); break;
2105 		CASE_TEST(htole32);                 EXPECT_EQ(1, htole32(is_le ? 0x01234567 : 0x67452301), 0x01234567); break;
2106 		CASE_TEST(htobe64);                 EXPECT_EQ(1, htobe64(is_le ? 0x0123456789000000 : 0x8967452301), 0x8967452301); break;
2107 		CASE_TEST(htole64);                 EXPECT_EQ(1, htole64(is_le ? 0x0123456789 : 0x8967452301000000), 0x0123456789); break;
2108 		CASE_TEST(wexitstatus);             EXPECT_EQ(1, WEXITSTATUS(0x1200), 0x12); break;
2109 		CASE_TEST(wifexited_exit0);         EXPECT_EQ(1, WIFEXITED(0), 1); break;
2110 		CASE_TEST(wifexited_signal);        EXPECT_EQ(1, WIFEXITED(SIGKILL), 0); break;
2111 		CASE_TEST(wifsignaled_exit0);       EXPECT_EQ(1, WIFSIGNALED(0), 0); break;
2112 		CASE_TEST(wifsignaled_exit);        EXPECT_EQ(1, WIFSIGNALED(0x1200), 0); break;
2113 		CASE_TEST(wifsignaled_signal);      EXPECT_EQ(1, WIFSIGNALED(SIGKILL), 1); break;
2114 		CASE_TEST(wifsignaled_stopped);     EXPECT_EQ(1, WIFSIGNALED((SIGSTOP << 8) | 0x7f), 0); break;
2115 		CASE_TEST(wtermsig_core);           EXPECT_EQ(1, WTERMSIG(0x80 | SIGSEGV), SIGSEGV); break;
2116 
2117 		case __LINE__:
2118 			return ret; /* must be last */
2119 		/* note: do not set any defaults so as to permit holes above */
2120 		}
2121 	}
2122 	return ret;
2123 }
2124 
2125 #define EXPECT_VFPRINTF(cond, expected, fmt, ...)				\
2126 	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_vfprintf(llen, expected, fmt, ##__VA_ARGS__); } while (0)
2127 
2128 #define VFPRINTF_LEN 25
expect_vfprintf(int llen,const char * expected,const char * fmt,...)2129 static int expect_vfprintf(int llen, const char *expected, const char *fmt, ...)
2130 {
2131 	char buf[VFPRINTF_LEN + 80];
2132 	unsigned int cmp_len;
2133 	va_list args;
2134 	ssize_t written, expected_len;
2135 
2136 	/* Fill and terminate buf[] to check for overlong/absent writes */
2137 	memset(buf, 0xa5, sizeof(buf) - 1);
2138 	buf[sizeof(buf) - 1] = 0;
2139 
2140 	va_start(args, fmt);
2141 	/* Limit buffer length to test truncation */
2142 	written = vsnprintf(buf, VFPRINTF_LEN + 1, fmt, args);
2143 	va_end(args);
2144 
2145 	llen += printf(" \"%s\"", buf);
2146 
2147 	expected_len = strlen(expected);
2148 	if (expected_len > VFPRINTF_LEN) {
2149 		/* Indicate truncated in test output */
2150 		llen += printf("+");
2151 		cmp_len = VFPRINTF_LEN;
2152 	} else {
2153 		cmp_len = expected_len;
2154 	}
2155 
2156 	if (memcmp(expected, buf, cmp_len) || buf[cmp_len]) {
2157 		llen += printf(" should be \"%.*s\"", VFPRINTF_LEN, expected);
2158 		result(llen, FAIL);
2159 		return 1;
2160 	}
2161 
2162 	if (written != expected_len) {
2163 		llen += printf(" written(%d) != %d", (int)written, (int)expected_len);
2164 		result(llen, FAIL);
2165 		return 1;
2166 	}
2167 
2168 	/* Check for any overwrites after the actual data. */
2169 	while (++cmp_len < sizeof(buf) - 1) {
2170 		if ((unsigned char)buf[cmp_len] != 0xa5) {
2171 			llen += printf(" overwrote buf[%d] with 0x%x", cmp_len, buf[cmp_len]);
2172 			result(llen, FAIL);
2173 			return 1;
2174 		}
2175 	}
2176 
2177 	result(llen, OK);
2178 	return 0;
2179 }
2180 
test_scanf(void)2181 static int test_scanf(void)
2182 {
2183 	unsigned long long ull;
2184 	unsigned long ul;
2185 	unsigned int u;
2186 	long long ll;
2187 	long l;
2188 	void *p;
2189 	int i;
2190 
2191 	/* return __LINE__ to point to the specific failure */
2192 
2193 	/* test EOF */
2194 	if (sscanf("", "foo") != EOF)
2195 		return __LINE__;
2196 
2197 	/* test simple literal without placeholder */
2198 	if (sscanf("foo", "foo") != 0)
2199 		return __LINE__;
2200 
2201 	/* test single placeholder */
2202 	if (sscanf("123", "%d", &i) != 1)
2203 		return __LINE__;
2204 
2205 	if (i != 123)
2206 		return __LINE__;
2207 
2208 	/* test multiple place holders and separators */
2209 	if (sscanf("a123b456c0x90", "a%db%uc%p", &i, &u, &p) != 3)
2210 		return __LINE__;
2211 
2212 	if (i != 123)
2213 		return __LINE__;
2214 
2215 	if (u != 456)
2216 		return __LINE__;
2217 
2218 	if (p != (void *)0x90)
2219 		return __LINE__;
2220 
2221 	/* test space handling */
2222 	if (sscanf("a    b1", "a b%d", &i) != 1)
2223 		return __LINE__;
2224 
2225 	if (i != 1)
2226 		return __LINE__;
2227 
2228 	/* test literal percent */
2229 	if (sscanf("a%1", "a%%%d", &i) != 1)
2230 		return __LINE__;
2231 
2232 	if (i != 1)
2233 		return __LINE__;
2234 
2235 	/* test stdint.h types */
2236 	if (sscanf("1|2|3|4|5|6",
2237 		   "%d|%ld|%lld|%u|%lu|%llu",
2238 		   &i, &l, &ll, &u, &ul, &ull) != 6)
2239 		return __LINE__;
2240 
2241 	if (i != 1 || l != 2 || ll != 3 ||
2242 	    u != 4 || ul != 5 || ull != 6)
2243 		return __LINE__;
2244 
2245 	return 0;
2246 }
2247 
test_printf_error(void)2248 static int test_printf_error(void)
2249 {
2250 	int fd, ret, saved_errno;
2251 
2252 	fd = open("/dev/full", O_RDWR);
2253 	if (fd == -1)
2254 		return 1;
2255 
2256 	errno = 0;
2257 	ret = dprintf(fd, "foo");
2258 	saved_errno = errno;
2259 	close(fd);
2260 
2261 	if (ret != -1)
2262 		return 2;
2263 
2264 	if (saved_errno != ENOSPC)
2265 		return 3;
2266 
2267 	return 0;
2268 }
2269 
test_asprintf(void)2270 int test_asprintf(void)
2271 {
2272 	char *str;
2273 	int ret;
2274 
2275 	ret = asprintf(&str, "foo%s", "bar");
2276 	if (ret == -1)
2277 		return 1;
2278 
2279 	if (ret != 6) {
2280 		free(str);
2281 		return 2;
2282 	}
2283 
2284 	if (memcmp(str, "foobar", 6) != 0) {
2285 		free(str);
2286 		return 3;
2287 	}
2288 
2289 	free(str);
2290 	return 0;
2291 }
2292 
run_printf(int min,int max)2293 static int run_printf(int min, int max)
2294 {
2295 	int test;
2296 	int ret = 0;
2297 
2298 	for (test = min; test >= 0 && test <= max; test++) {
2299 		int llen = 0; /* line length */
2300 
2301 		/* avoid leaving empty lines below, this will insert holes into
2302 		 * test numbers.
2303 		 */
2304 		switch (test + __LINE__ + 1) {
2305 		CASE_TEST(empty);        EXPECT_VFPRINTF(1, "", ""); break;
2306 		CASE_TEST(simple);       EXPECT_VFPRINTF(1, "foo", "foo"); break;
2307 		CASE_TEST(string);       EXPECT_VFPRINTF(1, "foo", "%s", "foo"); break;
2308 		CASE_TEST(number);       EXPECT_VFPRINTF(1, "1234", "%d", 1234); break;
2309 		CASE_TEST(negnumber);    EXPECT_VFPRINTF(1, "-1234", "%d", -1234); break;
2310 		CASE_TEST(num_sign);     EXPECT_VFPRINTF(1, "| 1|+2|+3|+4|5|", "|% d|%+d|% +d|%+ d|%#d|", 1, 2, 3, 4, 5); break;
2311 		CASE_TEST(unsigned);     EXPECT_VFPRINTF(1, "12345", "%u", 12345); break;
2312 		CASE_TEST(signed_max);   EXPECT_VFPRINTF(1, "2147483647", "%i", ~0u >> 1); break;
2313 		CASE_TEST(signed_min);   EXPECT_VFPRINTF(1, "-2147483648", "%i", (~0u >> 1) + 1); break;
2314 		CASE_TEST(unsigned_max); EXPECT_VFPRINTF(1, "4294967295", "%u", ~0u); break;
2315 		CASE_TEST(char);         EXPECT_VFPRINTF(1, "|c|d|   e|", "|%c|%.0c|%4c|", 'c', 'd', 'e'); break;
2316 		CASE_TEST(octal);        EXPECT_VFPRINTF(1, "|17|  0033||", "|%o|%6.4o|%.0o|", 017, 033, 0); break;
2317 		CASE_TEST(octal_max);    EXPECT_VFPRINTF(1, "1777777777777777777777", "%llo", ~0ULL); break;
2318 		CASE_TEST(octal_alt);    EXPECT_VFPRINTF(1, "|0|01|02|034|0|0|", "|%#o|%#o|%#02o|%#02o|%#.0o|%0-#o|", 0, 1, 2, 034, 0, 0); break;
2319 		CASE_TEST(hex_nolibc);   EXPECT_VFPRINTF(is_nolibc, "|f|d|", "|%x|%X|", 0xf, 0xd); break;
2320 		CASE_TEST(hex_libc);     EXPECT_VFPRINTF(!is_nolibc, "|f|D|", "|%x|%X|", 0xf, 0xd); break;
2321 		CASE_TEST(hex_alt);      EXPECT_VFPRINTF(1, "|0x1|  0x2|    0|", "|%#x|%#5x|%#5x|", 1, 2, 0); break;
2322 		CASE_TEST(hex_alt_prec); EXPECT_VFPRINTF(1, "| 0x02|0x03| 0x123|", "|%#5.2x|%#04x|%#6.2x|", 2, 3, 0x123); break;
2323 		CASE_TEST(hex_0_alt);    EXPECT_VFPRINTF(1, "|0|0000|   00|", "|%#x|%#04x|%#5.2x|", 0, 0, 0); break;
2324 		CASE_TEST(pointer);      EXPECT_VFPRINTF(1, "0x1", "%p", (void *) 0x1); break;
2325 		CASE_TEST(pointer_NULL); EXPECT_VFPRINTF(is_nolibc || is_glibc, "|(nil)|(nil)|", "|%p|%.4p|", (void *)0, (void *)0); break;
2326 		CASE_TEST(string_NULL);  EXPECT_VFPRINTF(is_nolibc || is_glibc, "|(null)||(null)|", "|%s|%.5s|%.6s|", (void *)0, (void *)0, (void *)0); break;
2327 		CASE_TEST(percent);      EXPECT_VFPRINTF(1, "a%d42%69%", "a%%d%d%%%d%%", 42, 69); break;
2328 		CASE_TEST(perc_qual);    EXPECT_VFPRINTF(is_nolibc || is_glibc, "a%d2", "a%-14l%d%d", 2); break;
2329 		CASE_TEST(invalid);      EXPECT_VFPRINTF(is_nolibc || is_glibc, "a%12yx3%y42%P", "a%12yx%d%y%d%P", 3, 42); break;
2330 		CASE_TEST(intmax_max);   EXPECT_VFPRINTF(1, "9223372036854775807", "%lld", ~0ULL >> 1); break;
2331 		CASE_TEST(intmax_min);   EXPECT_VFPRINTF(is_nolibc || is_glibc, "-9223372036854775808", "%Li", (~0ULL >> 1) + 1); break;
2332 		CASE_TEST(uintmax_max);  EXPECT_VFPRINTF(1, "18446744073709551615", "%ju", ~0ULL); break;
2333 		CASE_TEST(truncation);   EXPECT_VFPRINTF(1, "012345678901234567890123456789", "%s", "012345678901234567890123456789"); break;
2334 		CASE_TEST(string_width); EXPECT_VFPRINTF(1, "         1", "%10s", "1"); break;
2335 		CASE_TEST(string_trunc); EXPECT_VFPRINTF(1, "     12345", "%10.5s", "1234567890"); break;
2336 		CASE_TEST(string_var);   EXPECT_VFPRINTF(1, "| ab|ef | ij|kl |", "|%*.*s|%*.*s|%*.*s|%*.*s|", 3, 2, "abcd", -3, 2, "efgh", 3, -1, "ij", -3, -1, "kl"); break;
2337 		CASE_TEST(number_width); EXPECT_VFPRINTF(1, "         1", "%10d", 1); break;
2338 		CASE_TEST(number_left);  EXPECT_VFPRINTF(1, "|-5      |", "|%-8d|", -5); break;
2339 		CASE_TEST(string_align); EXPECT_VFPRINTF(1, "|foo     |", "|%-8s|", "foo"); break;
2340 		CASE_TEST(width_trunc);  EXPECT_VFPRINTF(1, "                             1", "%30d", 1); break;
2341 		CASE_TEST(width_tr_lft); EXPECT_VFPRINTF(1, "1                             ", "%-30d", 1); break;
2342 		CASE_TEST(number_pad);   EXPECT_VFPRINTF(1, "0000000005", "%010d", 5); break;
2343 		CASE_TEST(number_pad);   EXPECT_VFPRINTF(1, "|0000000005|0x1234|", "|%010d|%#01x|", 5, 0x1234); break;
2344 		CASE_TEST(num_pad_neg);  EXPECT_VFPRINTF(1, "-000000005", "%010d", -5); break;
2345 		CASE_TEST(num_pad_hex);  EXPECT_VFPRINTF(1, "00fffffffb", "%010x", -5); break;
2346 		CASE_TEST(num_pad_trunc);EXPECT_VFPRINTF(is_nolibc, "    0000000000000000000000000000005", "%035d", 5); break;  /* max 31 '0' can be added */
2347 		CASE_TEST(num_p_tr_libc);EXPECT_VFPRINTF(!is_nolibc, "00000000000000000000000000000000005", "%035d", 5); break;
2348 		CASE_TEST(number_prec);  EXPECT_VFPRINTF(1, "     00005", "%10.5d", 5); break;
2349 		CASE_TEST(num_prec_neg); EXPECT_VFPRINTF(1, "    -00005", "%10.5d", -5); break;
2350 		CASE_TEST(number_var);   EXPECT_VFPRINTF(1, "|    -00005|5 |", "|%*.*d|%*.*d|", 10, 5, -5, -2, -10, 5); break;
2351 		CASE_TEST(num_0_prec_0); EXPECT_VFPRINTF(1, "|| |+||||", "|%.0d|% .0d|%+.0d|%.0u|%.0x|%#.0x|", 0, 0, 0, 0, 0, 0); break;
2352 		CASE_TEST(errno);        errno = 22; EXPECT_VFPRINTF(is_nolibc, "errno=22", "%m"); break;
2353 		CASE_TEST(errno-neg);    errno = -22; EXPECT_VFPRINTF(is_nolibc, "errno=-22   ", "%-12m"); break;
2354 		CASE_TEST(scanf);        EXPECT_ZR(1, test_scanf()); break;
2355 		CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break;
2356 		CASE_TEST(asprintf);     EXPECT_ZR(1, test_asprintf()); break;
2357 		case __LINE__:
2358 			return ret; /* must be last */
2359 		/* note: do not set any defaults so as to permit holes above */
2360 		}
2361 	}
2362 	return ret;
2363 }
2364 
2365 __attribute__((no_sanitize("undefined")))
smash_stack(void)2366 static int smash_stack(void)
2367 {
2368 	char buf[100];
2369 	volatile char *ptr = buf;
2370 	size_t i;
2371 
2372 	for (i = 0; i < 200; i++)
2373 		ptr[i] = 'P';
2374 
2375 	return 1;
2376 }
2377 
run_protection(int min,int max)2378 static int run_protection(int min __attribute__((unused)),
2379 			  int max __attribute__((unused)))
2380 {
2381 	pid_t pid;
2382 	int llen = 0, status;
2383 	struct rlimit rlimit = { 0, 0 };
2384 
2385 	llen += printf("0 -fstackprotector ");
2386 
2387 #if !defined(_NOLIBC_STACKPROTECTOR)
2388 	llen += printf("not supported");
2389 	result(llen, SKIPPED);
2390 	return 0;
2391 #endif
2392 
2393 #if defined(_NOLIBC_STACKPROTECTOR)
2394 	if (!__stack_chk_guard) {
2395 		llen += printf("__stack_chk_guard not initialized");
2396 		result(llen, FAIL);
2397 		return 1;
2398 	}
2399 #endif
2400 
2401 	pid = -1;
2402 	pid = fork();
2403 
2404 	switch (pid) {
2405 	case -1:
2406 		llen += printf("fork()");
2407 		result(llen, FAIL);
2408 		return 1;
2409 
2410 	case 0:
2411 		close(STDOUT_FILENO);
2412 		close(STDERR_FILENO);
2413 
2414 		prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
2415 		setrlimit(RLIMIT_CORE, &rlimit);
2416 		smash_stack();
2417 		return 1;
2418 
2419 	default:
2420 		pid = waitpid(pid, &status, 0);
2421 
2422 		if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {
2423 			llen += printf("waitpid()");
2424 			result(llen, FAIL);
2425 			return 1;
2426 		}
2427 		result(llen, OK);
2428 		return 0;
2429 	}
2430 }
2431 
2432 /* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */
prepare(void)2433 int prepare(void)
2434 {
2435 	struct stat stat_buf;
2436 
2437 	/* It's possible that /dev doesn't even exist or was not mounted, so
2438 	 * we'll try to create it, mount it, or create minimal entries into it.
2439 	 * We want at least /dev/null and /dev/console.
2440 	 */
2441 	if (stat("/dev/.", &stat_buf) == 0 || mkdir("/dev", 0755) == 0) {
2442 		if (stat("/dev/console", &stat_buf) != 0 ||
2443 		    stat("/dev/null", &stat_buf) != 0 ||
2444 		    stat("/dev/zero", &stat_buf) != 0 ||
2445 		    stat("/dev/full", &stat_buf) != 0) {
2446 			/* try devtmpfs first, otherwise fall back to manual creation */
2447 			if (mount("/dev", "/dev", "devtmpfs", 0, 0) != 0) {
2448 				mknod("/dev/console", 0600 | S_IFCHR, makedev(5, 1));
2449 				mknod("/dev/null",    0666 | S_IFCHR, makedev(1, 3));
2450 				mknod("/dev/zero",    0666 | S_IFCHR, makedev(1, 5));
2451 				mknod("/dev/full",    0666 | S_IFCHR, makedev(1, 7));
2452 			}
2453 		}
2454 	}
2455 
2456 	/* If no /dev/console was found before calling init, stdio is closed so
2457 	 * we need to reopen it from /dev/console. If it failed above, it will
2458 	 * still fail here and we cannot emit a message anyway.
2459 	 */
2460 	if (close(dup(1)) == -1) {
2461 		int fd = open("/dev/console", O_RDWR);
2462 
2463 		if (fd >= 0) {
2464 			if (fd != 0)
2465 				dup2(fd, 0);
2466 			if (fd != 1)
2467 				dup2(fd, 1);
2468 			if (fd != 2)
2469 				dup2(fd, 2);
2470 			if (fd > 2)
2471 				close(fd);
2472 			puts("\nSuccessfully reopened /dev/console.");
2473 		}
2474 	}
2475 
2476 	/* try to mount /proc if not mounted. Silently fail otherwise */
2477 	if (stat("/proc/.", &stat_buf) == 0 || mkdir("/proc", 0755) == 0) {
2478 		if (stat("/proc/self", &stat_buf) != 0) {
2479 			/* If not mountable, remove /proc completely to avoid misuse */
2480 			if (mount("none", "/proc", "proc", 0, 0) != 0)
2481 				rmdir("/proc");
2482 		}
2483 	}
2484 
2485 	/* some tests rely on a writable /tmp */
2486 	mkdir("/tmp", 0755);
2487 
2488 	return 0;
2489 }
2490 
2491 /* This is the definition of known test names, with their functions */
2492 static const struct test test_names[] = {
2493 	/* add new tests here */
2494 	{ .name = "startup",    .func = run_startup    },
2495 	{ .name = "syscall",    .func = run_syscall    },
2496 	{ .name = "stdlib",     .func = run_stdlib     },
2497 	{ .name = "printf",     .func = run_printf     },
2498 	{ .name = "protection", .func = run_protection },
2499 	{ 0 }
2500 };
2501 
is_setting_valid(char * test)2502 static int is_setting_valid(char *test)
2503 {
2504 	int idx, len, test_len, valid = 0;
2505 	char delimiter;
2506 
2507 	if (!test)
2508 		return valid;
2509 
2510 	test_len = strlen(test);
2511 
2512 	for (idx = 0; test_names[idx].name; idx++) {
2513 		len = strlen(test_names[idx].name);
2514 		if (test_len < len)
2515 			continue;
2516 
2517 		if (strncmp(test, test_names[idx].name, len) != 0)
2518 			continue;
2519 
2520 		delimiter = test[len];
2521 		if (delimiter != ':' && delimiter != ',' && delimiter != '\0')
2522 			continue;
2523 
2524 		valid = 1;
2525 		break;
2526 	}
2527 
2528 	return valid;
2529 }
2530 
main(int argc,char ** argv,char ** envp)2531 int main(int argc, char **argv, char **envp)
2532 {
2533 	int min = 0;
2534 	int max = INT_MAX;
2535 	int ret = 0;
2536 	int err;
2537 	int idx;
2538 	char *test;
2539 
2540 	argv0 = argv[0];
2541 	test_argc = argc;
2542 	test_argv = argv;
2543 	test_envp = envp;
2544 
2545 	/* when called as init, it's possible that no console was opened, for
2546 	 * example if no /dev file system was provided. We'll check that fd#1
2547 	 * was opened, and if not we'll attempt to create and open /dev/console
2548 	 * and /dev/null that we'll use for later tests.
2549 	 */
2550 	if (getpid() == 1)
2551 		prepare();
2552 
2553 	/* the definition of a series of tests comes from either argv[1] or the
2554 	 * "NOLIBC_TEST" environment variable. It's made of a comma-delimited
2555 	 * series of test names and optional ranges:
2556 	 *    syscall:5-15[:.*],stdlib:8-10
2557 	 */
2558 	test = argv[1];
2559 	if (!is_setting_valid(test))
2560 		test = getenv("NOLIBC_TEST");
2561 
2562 	if (is_setting_valid(test)) {
2563 		char *comma, *colon, *dash, *value;
2564 
2565 		do {
2566 			comma = strchr(test, ',');
2567 			if (comma)
2568 				*(comma++) = '\0';
2569 
2570 			colon = strchr(test, ':');
2571 			if (colon)
2572 				*(colon++) = '\0';
2573 
2574 			for (idx = 0; test_names[idx].name; idx++) {
2575 				if (strcmp(test, test_names[idx].name) == 0)
2576 					break;
2577 			}
2578 
2579 			if (test_names[idx].name) {
2580 				/* The test was named, it will be called at least
2581 				 * once. We may have an optional range at <colon>
2582 				 * here, which defaults to the full range.
2583 				 */
2584 				do {
2585 					min = 0; max = INT_MAX;
2586 					value = colon;
2587 					if (value && *value) {
2588 						colon = strchr(value, ':');
2589 						if (colon)
2590 							*(colon++) = '\0';
2591 
2592 						dash = strchr(value, '-');
2593 						if (dash)
2594 							*(dash++) = '\0';
2595 
2596 						/* support :val: :min-max: :min-: :-max: */
2597 						if (*value)
2598 							min = atoi(value);
2599 						if (!dash)
2600 							max = min;
2601 						else if (*dash)
2602 							max = atoi(dash);
2603 
2604 						value = colon;
2605 					}
2606 
2607 					/* now's time to call the test */
2608 					printf("Running test '%s'\n", test_names[idx].name);
2609 					err = test_names[idx].func(min, max);
2610 					ret += err;
2611 					printf("Errors during this test: %d\n\n", err);
2612 				} while (colon && *colon);
2613 			} else
2614 				printf("Ignoring unknown test name '%s'\n", test);
2615 
2616 			test = comma;
2617 		} while (test && *test);
2618 	} else {
2619 		/* no test mentioned, run everything */
2620 		for (idx = 0; test_names[idx].name; idx++) {
2621 			printf("Running test '%s'\n", test_names[idx].name);
2622 			err = test_names[idx].func(min, max);
2623 			ret += err;
2624 			printf("Errors during this test: %d\n\n", err);
2625 		}
2626 	}
2627 
2628 	printf("Total number of errors: %d\n", ret);
2629 
2630 	if (getpid() == 1) {
2631 		/* we're running as init, there's no other process on the
2632 		 * system, thus likely started from a VM for a quick check.
2633 		 * Exiting will provoke a kernel panic that may be reported
2634 		 * as an error by Qemu or the hypervisor, while stopping
2635 		 * cleanly will often be reported as a success. This allows
2636 		 * to use the output of this program for bisecting kernels.
2637 		 */
2638 		printf("Leaving init with final status: %d\n", !!ret);
2639 		if (ret == 0)
2640 			reboot(RB_POWER_OFF);
2641 #if defined(__x86_64__)
2642 		/* QEMU started with "-device isa-debug-exit -no-reboot" will
2643 		 * exit with status code 2N+1 when N is written to 0x501. We
2644 		 * hard-code the syscall here as it's arch-dependent.
2645 		 */
2646 		else if (syscall(__NR_ioperm, 0x501, 1, 1) == 0)
2647 			__asm__ volatile ("outb %%al, %%dx" :: "d"(0x501), "a"(0));
2648 		/* if it does nothing, fall back to the regular panic */
2649 #endif
2650 	}
2651 
2652 	printf("Exiting with status %d\n", !!ret);
2653 	return !!ret;
2654 }
2655