brintos

brintos / linux-shallow public Read only

0
0
Text · 48.8 KiB · 6fba702 Raw
1597 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2 3#define _GNU_SOURCE4#define _LARGEFILE64_SOURCE5 6/* libc-specific include files7 * The program may be built in 3 ways:8 *   $(CC) -nostdlib -include /path/to/nolibc.h => NOLIBC already defined9 *   $(CC) -nostdlib -I/path/to/nolibc/sysroot  => _NOLIBC_* guards are present10 *   $(CC) with default libc                    => NOLIBC* never defined11 */12#ifndef NOLIBC13#include <stdio.h>14#include <stdlib.h>15#include <string.h>16#ifndef _NOLIBC_STDIO_H17/* standard libcs need more includes */18#include <sys/auxv.h>19#include <sys/io.h>20#include <sys/ioctl.h>21#include <sys/mman.h>22#include <sys/mount.h>23#include <sys/prctl.h>24#include <sys/reboot.h>25#include <sys/resource.h>26#include <sys/stat.h>27#include <sys/syscall.h>28#include <sys/sysmacros.h>29#include <sys/time.h>30#include <sys/utsname.h>31#include <sys/wait.h>32#include <dirent.h>33#include <errno.h>34#include <fcntl.h>35#include <poll.h>36#include <sched.h>37#include <signal.h>38#include <stdarg.h>39#include <stddef.h>40#include <stdint.h>41#include <unistd.h>42#include <limits.h>43#endif44#endif45 46#include "nolibc-test-linkage.h"47 48/* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */49#define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))50#define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)51 52/* will be used to test initialization of environ */53static char **test_envp;54 55/* will be used to test initialization of argv */56static char **test_argv;57 58/* will be used to test initialization of argc */59static int test_argc;60 61/* will be used by some test cases as readable file, please don't write it */62static const char *argv0;63 64/* will be used by constructor tests */65static int constructor_test_value;66 67static const int is_nolibc =68#ifdef NOLIBC69	170#else71	072#endif73;74 75/* definition of a series of tests */76struct test {77	const char *name;              /* test name */78	int (*func)(int min, int max); /* handler */79};80 81#ifndef _NOLIBC_STDLIB_H82char *itoa(int i)83{84	static char buf[12];85	int ret;86 87	ret = snprintf(buf, sizeof(buf), "%d", i);88	return (ret >= 0 && ret < sizeof(buf)) ? buf : "#err";89}90#endif91 92#define CASE_ERR(err) \93	case err: return #err94 95/* returns the error name (e.g. "ENOENT") for common errors, "SUCCESS" for 0,96 * or the decimal value for less common ones.97 */98static const char *errorname(int err)99{100	switch (err) {101	case 0: return "SUCCESS";102	CASE_ERR(EPERM);103	CASE_ERR(ENOENT);104	CASE_ERR(ESRCH);105	CASE_ERR(EINTR);106	CASE_ERR(EIO);107	CASE_ERR(ENXIO);108	CASE_ERR(E2BIG);109	CASE_ERR(ENOEXEC);110	CASE_ERR(EBADF);111	CASE_ERR(ECHILD);112	CASE_ERR(EAGAIN);113	CASE_ERR(ENOMEM);114	CASE_ERR(EACCES);115	CASE_ERR(EFAULT);116	CASE_ERR(ENOTBLK);117	CASE_ERR(EBUSY);118	CASE_ERR(EEXIST);119	CASE_ERR(EXDEV);120	CASE_ERR(ENODEV);121	CASE_ERR(ENOTDIR);122	CASE_ERR(EISDIR);123	CASE_ERR(EINVAL);124	CASE_ERR(ENFILE);125	CASE_ERR(EMFILE);126	CASE_ERR(ENOTTY);127	CASE_ERR(ETXTBSY);128	CASE_ERR(EFBIG);129	CASE_ERR(ENOSPC);130	CASE_ERR(ESPIPE);131	CASE_ERR(EROFS);132	CASE_ERR(EMLINK);133	CASE_ERR(EPIPE);134	CASE_ERR(EDOM);135	CASE_ERR(ERANGE);136	CASE_ERR(ENOSYS);137	CASE_ERR(EOVERFLOW);138	default:139		return itoa(err);140	}141}142 143static void align_result(size_t llen)144{145	const size_t align = 64;146	char buf[align];147	size_t n;148 149	if (llen >= align)150		return;151 152	n = align - llen;153	memset(buf, ' ', n);154	buf[n] = '\0';155	fputs(buf, stdout);156}157 158enum RESULT {159	OK,160	FAIL,161	SKIPPED,162};163 164static void result(int llen, enum RESULT r)165{166	const char *msg;167 168	if (r == OK)169		msg = "  [OK]";170	else if (r == SKIPPED)171		msg = "[SKIPPED]";172	else173		msg = " [FAIL]";174 175	align_result(llen);176	puts(msg);177}178 179/* The tests below are intended to be used by the macroes, which evaluate180 * expression <expr>, print the status to stdout, and update the "ret"181 * variable to count failures. The functions themselves return the number182 * of failures, thus either 0 or 1.183 */184 185#define EXPECT_ZR(cond, expr)				\186	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_zr(expr, llen); } while (0)187 188static __attribute__((unused))189int expect_zr(int expr, int llen)190{191	int ret = !(expr == 0);192 193	llen += printf(" = %d ", expr);194	result(llen, ret ? FAIL : OK);195	return ret;196}197 198 199#define EXPECT_NZ(cond, expr, val)			\200	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_nz(expr, llen; } while (0)201 202static __attribute__((unused))203int expect_nz(int expr, int llen)204{205	int ret = !(expr != 0);206 207	llen += printf(" = %d ", expr);208	result(llen, ret ? FAIL : OK);209	return ret;210}211 212 213#define EXPECT_EQ(cond, expr, val)				\214	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_eq(expr, llen, val); } while (0)215 216static __attribute__((unused))217int expect_eq(uint64_t expr, int llen, uint64_t val)218{219	int ret = !(expr == val);220 221	llen += printf(" = %lld ", (long long)expr);222	result(llen, ret ? FAIL : OK);223	return ret;224}225 226 227#define EXPECT_NE(cond, expr, val)				\228	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ne(expr, llen, val); } while (0)229 230static __attribute__((unused))231int expect_ne(int expr, int llen, int val)232{233	int ret = !(expr != val);234 235	llen += printf(" = %d ", expr);236	result(llen, ret ? FAIL : OK);237	return ret;238}239 240 241#define EXPECT_GE(cond, expr, val)				\242	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ge(expr, llen, val); } while (0)243 244static __attribute__((unused))245int expect_ge(int expr, int llen, int val)246{247	int ret = !(expr >= val);248 249	llen += printf(" = %d ", expr);250	result(llen, ret ? FAIL : OK);251	return ret;252}253 254 255#define EXPECT_GT(cond, expr, val)				\256	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_gt(expr, llen, val); } while (0)257 258static __attribute__((unused))259int expect_gt(int expr, int llen, int val)260{261	int ret = !(expr > val);262 263	llen += printf(" = %d ", expr);264	result(llen, ret ? FAIL : OK);265	return ret;266}267 268 269#define EXPECT_LE(cond, expr, val)				\270	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_le(expr, llen, val); } while (0)271 272static __attribute__((unused))273int expect_le(int expr, int llen, int val)274{275	int ret = !(expr <= val);276 277	llen += printf(" = %d ", expr);278	result(llen, ret ? FAIL : OK);279	return ret;280}281 282 283#define EXPECT_LT(cond, expr, val)				\284	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_lt(expr, llen, val); } while (0)285 286static __attribute__((unused))287int expect_lt(int expr, int llen, int val)288{289	int ret = !(expr < val);290 291	llen += printf(" = %d ", expr);292	result(llen, ret ? FAIL : OK);293	return ret;294}295 296 297#define EXPECT_SYSZR(cond, expr)				\298	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syszr(expr, llen); } while (0)299 300static __attribute__((unused))301int expect_syszr(int expr, int llen)302{303	int ret = 0;304 305	if (expr) {306		ret = 1;307		llen += printf(" = %d %s ", expr, errorname(errno));308		result(llen, FAIL);309	} else {310		llen += printf(" = %d ", expr);311		result(llen, OK);312	}313	return ret;314}315 316 317#define EXPECT_SYSEQ(cond, expr, val)				\318	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syseq(expr, llen, val); } while (0)319 320static __attribute__((unused))321int expect_syseq(int expr, int llen, int val)322{323	int ret = 0;324 325	if (expr != val) {326		ret = 1;327		llen += printf(" = %d %s ", expr, errorname(errno));328		result(llen, FAIL);329	} else {330		llen += printf(" = %d ", expr);331		result(llen, OK);332	}333	return ret;334}335 336 337#define EXPECT_SYSNE(cond, expr, val)				\338	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_sysne(expr, llen, val); } while (0)339 340static __attribute__((unused))341int expect_sysne(int expr, int llen, int val)342{343	int ret = 0;344 345	if (expr == val) {346		ret = 1;347		llen += printf(" = %d %s ", expr, errorname(errno));348		result(llen, FAIL);349	} else {350		llen += printf(" = %d ", expr);351		result(llen, OK);352	}353	return ret;354}355 356 357#define EXPECT_SYSER2(cond, expr, expret, experr1, experr2)		\358	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_syserr2(expr, expret, experr1, experr2, llen); } while (0)359 360#define EXPECT_SYSER(cond, expr, expret, experr)			\361	EXPECT_SYSER2(cond, expr, expret, experr, 0)362 363static __attribute__((unused))364int expect_syserr2(int expr, int expret, int experr1, int experr2, int llen)365{366	int ret = 0;367	int _errno = errno;368 369	llen += printf(" = %d %s ", expr, errorname(_errno));370	if (expr != expret || (_errno != experr1 && _errno != experr2)) {371		ret = 1;372		if (experr2 == 0)373			llen += printf(" != (%d %s) ", expret, errorname(experr1));374		else375			llen += printf(" != (%d %s %s) ", expret, errorname(experr1), errorname(experr2));376		result(llen, FAIL);377	} else {378		result(llen, OK);379	}380	return ret;381}382 383 384#define EXPECT_PTRZR(cond, expr)				\385	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrzr(expr, llen); } while (0)386 387static __attribute__((unused))388int expect_ptrzr(const void *expr, int llen)389{390	int ret = 0;391 392	llen += printf(" = <%p> ", expr);393	if (expr) {394		ret = 1;395		result(llen, FAIL);396	} else {397		result(llen, OK);398	}399	return ret;400}401 402 403#define EXPECT_PTRNZ(cond, expr)				\404	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrnz(expr, llen); } while (0)405 406static __attribute__((unused))407int expect_ptrnz(const void *expr, int llen)408{409	int ret = 0;410 411	llen += printf(" = <%p> ", expr);412	if (!expr) {413		ret = 1;414		result(llen, FAIL);415	} else {416		result(llen, OK);417	}418	return ret;419}420 421#define EXPECT_PTREQ(cond, expr, cmp)				\422	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptreq(expr, llen, cmp); } while (0)423 424static __attribute__((unused))425int expect_ptreq(const void *expr, int llen, const void *cmp)426{427	int ret = 0;428 429	llen += printf(" = <%p> ", expr);430	if (expr != cmp) {431		ret = 1;432		result(llen, FAIL);433	} else {434		result(llen, OK);435	}436	return ret;437}438 439#define EXPECT_PTRNE(cond, expr, cmp)				\440	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrne(expr, llen, cmp); } while (0)441 442static __attribute__((unused))443int expect_ptrne(const void *expr, int llen, const void *cmp)444{445	int ret = 0;446 447	llen += printf(" = <%p> ", expr);448	if (expr == cmp) {449		ret = 1;450		result(llen, FAIL);451	} else {452		result(llen, OK);453	}454	return ret;455}456 457#define EXPECT_PTRGE(cond, expr, cmp)				\458	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrge(expr, llen, cmp); } while (0)459 460static __attribute__((unused))461int expect_ptrge(const void *expr, int llen, const void *cmp)462{463	int ret = !(expr >= cmp);464 465	llen += printf(" = <%p> ", expr);466	result(llen, ret ? FAIL : OK);467	return ret;468}469 470#define EXPECT_PTRGT(cond, expr, cmp)				\471	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrgt(expr, llen, cmp); } while (0)472 473static __attribute__((unused))474int expect_ptrgt(const void *expr, int llen, const void *cmp)475{476	int ret = !(expr > cmp);477 478	llen += printf(" = <%p> ", expr);479	result(llen, ret ? FAIL : OK);480	return ret;481}482 483 484#define EXPECT_PTRLE(cond, expr, cmp)				\485	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrle(expr, llen, cmp); } while (0)486 487static __attribute__((unused))488int expect_ptrle(const void *expr, int llen, const void *cmp)489{490	int ret = !(expr <= cmp);491 492	llen += printf(" = <%p> ", expr);493	result(llen, ret ? FAIL : OK);494	return ret;495}496 497 498#define EXPECT_PTRLT(cond, expr, cmp)				\499	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrlt(expr, llen, cmp); } while (0)500 501static __attribute__((unused))502int expect_ptrlt(const void *expr, int llen, const void *cmp)503{504	int ret = !(expr < cmp);505 506	llen += printf(" = <%p> ", expr);507	result(llen, ret ? FAIL : OK);508	return ret;509}510 511#define EXPECT_PTRER2(cond, expr, expret, experr1, experr2)		\512	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrerr2(expr, expret, experr1, experr2, llen); } while (0)513 514#define EXPECT_PTRER(cond, expr, expret, experr)			\515	EXPECT_PTRER2(cond, expr, expret, experr, 0)516 517static __attribute__((unused))518int expect_ptrerr2(const void *expr, const void *expret, int experr1, int experr2, int llen)519{520	int ret = 0;521	int _errno = errno;522 523	llen += printf(" = <%p> %s ", expr, errorname(_errno));524	if (expr != expret || (_errno != experr1 && _errno != experr2)) {525		ret = 1;526		if (experr2 == 0)527			llen += printf(" != (<%p> %s) ", expret, errorname(experr1));528		else529			llen += printf(" != (<%p> %s %s) ", expret, errorname(experr1), errorname(experr2));530		result(llen, FAIL);531	} else {532		result(llen, OK);533	}534	return ret;535}536 537#define EXPECT_STRZR(cond, expr)				\538	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strzr(expr, llen); } while (0)539 540static __attribute__((unused))541int expect_strzr(const char *expr, int llen)542{543	int ret = 0;544 545	llen += printf(" = <%s> ", expr ? expr : "(null)");546	if (expr) {547		ret = 1;548		result(llen, FAIL);549	} else {550		result(llen, OK);551	}552	return ret;553}554 555 556#define EXPECT_STRNZ(cond, expr)				\557	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strnz(expr, llen); } while (0)558 559static __attribute__((unused))560int expect_strnz(const char *expr, int llen)561{562	int ret = 0;563 564	llen += printf(" = <%s> ", expr ? expr : "(null)");565	if (!expr) {566		ret = 1;567		result(llen, FAIL);568	} else {569		result(llen, OK);570	}571	return ret;572}573 574 575#define EXPECT_STREQ(cond, expr, cmp)				\576	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_streq(expr, llen, cmp); } while (0)577 578static __attribute__((unused))579int expect_streq(const char *expr, int llen, const char *cmp)580{581	int ret = 0;582 583	llen += printf(" = <%s> ", expr);584	if (strcmp(expr, cmp) != 0) {585		ret = 1;586		result(llen, FAIL);587	} else {588		result(llen, OK);589	}590	return ret;591}592 593 594#define EXPECT_STRNE(cond, expr, cmp)				\595	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strne(expr, llen, cmp); } while (0)596 597static __attribute__((unused))598int expect_strne(const char *expr, int llen, const char *cmp)599{600	int ret = 0;601 602	llen += printf(" = <%s> ", expr);603	if (strcmp(expr, cmp) == 0) {604		ret = 1;605		result(llen, FAIL);606	} else {607		result(llen, OK);608	}609	return ret;610}611 612#define EXPECT_STRBUFEQ(cond, expr, buf, val, cmp)				\613	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_str_buf_eq(expr, buf, val, llen, cmp); } while (0)614 615static __attribute__((unused))616int expect_str_buf_eq(size_t expr, const char *buf, size_t val, int llen, const char *cmp)617{618	llen += printf(" = %lu <%s> ", (unsigned long)expr, buf);619	if (strcmp(buf, cmp) != 0) {620		result(llen, FAIL);621		return 1;622	}623	if (expr != val) {624		result(llen, FAIL);625		return 1;626	}627 628	result(llen, OK);629	return 0;630}631 632#define EXPECT_STRTOX(cond, func, input, base, expected, chars, expected_errno)				\633	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strtox(llen, func, input, base, expected, chars, expected_errno); } while (0)634 635static __attribute__((unused))636int expect_strtox(int llen, void *func, const char *input, int base, intmax_t expected, int expected_chars, int expected_errno)637{638	char *endptr;639	int actual_errno, actual_chars;640	intmax_t r;641 642	errno = 0;643	if (func == strtol) {644		r = strtol(input, &endptr, base);645	} else if (func == strtoul) {646		r = strtoul(input, &endptr, base);647	} else {648		result(llen, FAIL);649		return 1;650	}651	actual_errno = errno;652	actual_chars = endptr - input;653 654	llen += printf(" %lld = %lld", (long long)expected, (long long)r);655	if (r != expected) {656		result(llen, FAIL);657		return 1;658	}659	if (expected_chars == -1) {660		if (*endptr != '\0') {661			result(llen, FAIL);662			return 1;663		}664	} else if (expected_chars != actual_chars) {665		result(llen, FAIL);666		return 1;667	}668	if (actual_errno != expected_errno) {669		result(llen, FAIL);670		return 1;671	}672 673	result(llen, OK);674	return 0;675}676 677/* declare tests based on line numbers. There must be exactly one test per line. */678#define CASE_TEST(name) \679	case __LINE__: llen += printf("%d %s", test, #name);680 681/* constructors validate that they are executed in definition order */682__attribute__((constructor))683static void constructor1(void)684{685	constructor_test_value = 1;686}687 688__attribute__((constructor))689static void constructor2(int argc, char **argv, char **envp)690{691	if (argc && argv && envp)692		constructor_test_value *= 2;693}694 695int run_startup(int min, int max)696{697	int test;698	int ret = 0;699	/* kernel at least passes HOME and TERM, shell passes more */700	int env_total = 2;701	/* checking NULL for argv/argv0, environ and _auxv is not enough, let's compare with sbrk(0) or &end */702	extern char end;703	char *brk = sbrk(0) != (void *)-1 ? sbrk(0) : &end;704	/* differ from nolibc, both glibc and musl have no global _auxv */705	const unsigned long *test_auxv = (void *)-1;706#ifdef NOLIBC707	test_auxv = _auxv;708#endif709 710	for (test = min; test >= 0 && test <= max; test++) {711		int llen = 0; /* line length */712 713		/* avoid leaving empty lines below, this will insert holes into714		 * test numbers.715		 */716		switch (test + __LINE__ + 1) {717		CASE_TEST(argc);             EXPECT_GE(1, test_argc, 1); break;718		CASE_TEST(argv_addr);        EXPECT_PTRGT(1, test_argv, brk); break;719		CASE_TEST(argv_environ);     EXPECT_PTRLT(1, test_argv, environ); break;720		CASE_TEST(argv_total);       EXPECT_EQ(1, environ - test_argv - 1, test_argc ?: 1); break;721		CASE_TEST(argv0_addr);       EXPECT_PTRGT(1, argv0, brk); break;722		CASE_TEST(argv0_str);        EXPECT_STRNZ(1, argv0 > brk ? argv0 : NULL); break;723		CASE_TEST(argv0_len);        EXPECT_GE(1,  argv0 > brk ? strlen(argv0) : 0, 1); break;724		CASE_TEST(environ_addr);     EXPECT_PTRGT(1, environ, brk); break;725		CASE_TEST(environ_envp);     EXPECT_PTREQ(1, environ, test_envp); break;726		CASE_TEST(environ_auxv);     EXPECT_PTRLT(test_auxv != (void *)-1, environ, test_auxv); break;727		CASE_TEST(environ_total);    EXPECT_GE(test_auxv != (void *)-1, (void *)test_auxv - (void *)environ - 1, env_total); break;728		CASE_TEST(environ_HOME);     EXPECT_PTRNZ(1, getenv("HOME")); break;729		CASE_TEST(auxv_addr);        EXPECT_PTRGT(test_auxv != (void *)-1, test_auxv, brk); break;730		CASE_TEST(auxv_AT_UID);      EXPECT_EQ(1, getauxval(AT_UID), getuid()); break;731		CASE_TEST(constructor);      EXPECT_EQ(1, constructor_test_value, 2); break;732		CASE_TEST(linkage_errno);    EXPECT_PTREQ(1, linkage_test_errno_addr(), &errno); break;733		CASE_TEST(linkage_constr);   EXPECT_EQ(1, linkage_test_constructor_test_value, 6); break;734		case __LINE__:735			return ret; /* must be last */736		/* note: do not set any defaults so as to permit holes above */737		}738	}739	return ret;740}741 742 743/* used by some syscall tests below */744int test_getdents64(const char *dir)745{746	char buffer[4096];747	int fd, ret;748	int err;749 750	ret = fd = open(dir, O_RDONLY | O_DIRECTORY, 0);751	if (ret < 0)752		return ret;753 754	ret = getdents64(fd, (void *)buffer, sizeof(buffer));755	err = errno;756	close(fd);757 758	errno = err;759	return ret;760}761 762int test_getpagesize(void)763{764	int x = getpagesize();765	int c;766 767	if (x < 0)768		return x;769 770#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)771	/*772	 * x86 family is always 4K page.773	 */774	c = (x == 4096);775#elif defined(__aarch64__)776	/*777	 * Linux aarch64 supports three values of page size: 4K, 16K, and 64K778	 * which are selected at kernel compilation time.779	 */780	c = (x == 4096 || x == (16 * 1024) || x == (64 * 1024));781#else782	/*783	 * Assuming other architectures must have at least 4K page.784	 */785	c = (x >= 4096);786#endif787 788	return !c;789}790 791int test_fork(void)792{793	int status;794	pid_t pid;795 796	/* flush the printf buffer to avoid child flush it */797	fflush(stdout);798	fflush(stderr);799 800	pid = fork();801 802	switch (pid) {803	case -1:804		return 1;805 806	case 0:807		exit(123);808 809	default:810		pid = waitpid(pid, &status, 0);811 812		return pid == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 123;813	}814}815 816int test_stat_timestamps(void)817{818	struct stat st;819 820	if (sizeof(st.st_atim.tv_sec) != sizeof(st.st_atime))821		return 1;822 823	if (stat("/proc/self/", &st) && stat(argv0, &st) && stat("/", &st))824		return 1;825 826	if (st.st_atim.tv_sec != st.st_atime || st.st_atim.tv_nsec > 1000000000)827		return 1;828 829	if (st.st_mtim.tv_sec != st.st_mtime || st.st_mtim.tv_nsec > 1000000000)830		return 1;831 832	if (st.st_ctim.tv_sec != st.st_ctime || st.st_ctim.tv_nsec > 1000000000)833		return 1;834 835	return 0;836}837 838int test_uname(void)839{840	struct utsname buf;841	char osrelease[sizeof(buf.release)];842	ssize_t r;843	int fd;844 845	memset(&buf.domainname, 'P', sizeof(buf.domainname));846 847	if (uname(&buf))848		return 1;849 850	if (strncmp("Linux", buf.sysname, sizeof(buf.sysname)))851		return 1;852 853	fd = open("/proc/sys/kernel/osrelease", O_RDONLY);854	if (fd == -1)855		return 1;856 857	r = read(fd, osrelease, sizeof(osrelease));858	if (r == -1)859		return 1;860 861	close(fd);862 863	if (osrelease[r - 1] == '\n')864		r--;865 866	/* Validate one of the later fields to ensure field sizes are correct */867	if (strncmp(osrelease, buf.release, r))868		return 1;869 870	/* Ensure the field domainname is set, it is missing from struct old_utsname */871	if (strnlen(buf.domainname, sizeof(buf.domainname)) == sizeof(buf.domainname))872		return 1;873 874	return 0;875}876 877int test_mmap_munmap(void)878{879	int ret, fd, i, page_size;880	void *mem;881	size_t file_size, length;882	off_t offset, pa_offset;883	struct stat stat_buf;884	const char * const files[] = {885		"/dev/zero",886		"/proc/1/exe", "/proc/self/exe",887		argv0,888		NULL889	};890 891	page_size = getpagesize();892	if (page_size < 0)893		return 1;894 895	/* find a right file to mmap, existed and accessible */896	for (i = 0; files[i] != NULL; i++) {897		ret = fd = open(files[i], O_RDONLY);898		if (ret == -1)899			continue;900		else901			break;902	}903	if (ret == -1)904		return 1;905 906	ret = stat(files[i], &stat_buf);907	if (ret == -1)908		goto end;909 910	/* file size of the special /dev/zero is 0, let's assign one manually */911	if (i == 0)912		file_size = 3*page_size;913	else914		file_size = stat_buf.st_size;915 916	offset = file_size - 1;917	if (offset < 0)918		offset = 0;919	length = file_size - offset;920	pa_offset = offset & ~(page_size - 1);921 922	mem = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_SHARED, fd, pa_offset);923	if (mem == MAP_FAILED) {924		ret = 1;925		goto end;926	}927 928	ret = munmap(mem, length + offset - pa_offset);929 930end:931	close(fd);932	return !!ret;933}934 935int test_pipe(void)936{937	const char *const msg = "hello, nolibc";938	int pipefd[2];939	char buf[32];940	size_t len;941 942	if (pipe(pipefd) == -1)943		return 1;944 945	write(pipefd[1], msg, strlen(msg));946	close(pipefd[1]);947	len = read(pipefd[0], buf, sizeof(buf));948	close(pipefd[0]);949 950	if (len != strlen(msg))951		return 1;952 953	return !!memcmp(buf, msg, len);954}955 956int test_rlimit(void)957{958	struct rlimit rlim = {959		.rlim_cur = 1 << 20,960		.rlim_max = 1 << 21,961	};962	int ret;963 964	ret = setrlimit(RLIMIT_CORE, &rlim);965	if (ret)966		return -1;967 968	rlim.rlim_cur = 0;969	rlim.rlim_max = 0;970 971	ret = getrlimit(RLIMIT_CORE, &rlim);972	if (ret)973		return -1;974 975	if (rlim.rlim_cur != 1 << 20)976		return -1;977	if (rlim.rlim_max != 1 << 21)978		return -1;979 980	return 0;981}982 983 984/* Run syscall tests between IDs <min> and <max>.985 * Return 0 on success, non-zero on failure.986 */987int run_syscall(int min, int max)988{989	struct timeval tv;990	struct timezone tz;991	struct stat stat_buf;992	int euid0;993	int proc;994	int test;995	int tmp;996	int ret = 0;997	void *p1, *p2;998	int has_gettid = 1;999	int has_brk;1000 1001	/* <proc> indicates whether or not /proc is mounted */1002	proc = stat("/proc", &stat_buf) == 0;1003 1004	/* this will be used to skip certain tests that can't be run unprivileged */1005	euid0 = geteuid() == 0;1006 1007	/* from 2.30, glibc provides gettid() */1008#if defined(__GLIBC_MINOR__) && defined(__GLIBC__)1009	has_gettid = __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 30);1010#endif1011 1012	/* on musl setting brk()/sbrk() always fails */1013	has_brk = brk(0) == 0;1014 1015	for (test = min; test >= 0 && test <= max; test++) {1016		int llen = 0; /* line length */1017 1018		/* avoid leaving empty lines below, this will insert holes into1019		 * test numbers.1020		 */1021		switch (test + __LINE__ + 1) {1022		CASE_TEST(getpid);            EXPECT_SYSNE(1, getpid(), -1); break;1023		CASE_TEST(getppid);           EXPECT_SYSNE(1, getppid(), -1); break;1024		CASE_TEST(gettid);            EXPECT_SYSNE(has_gettid, gettid(), -1); break;1025		CASE_TEST(getpgid_self);      EXPECT_SYSNE(1, getpgid(0), -1); break;1026		CASE_TEST(getpgid_bad);       EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break;1027		CASE_TEST(kill_0);            EXPECT_SYSZR(1, kill(getpid(), 0)); break;1028		CASE_TEST(kill_CONT);         EXPECT_SYSZR(1, kill(getpid(), 0)); break;1029		CASE_TEST(kill_BADPID);       EXPECT_SYSER(1, kill(INT_MAX, 0), -1, ESRCH); break;1030		CASE_TEST(sbrk_0);            EXPECT_PTRNE(has_brk, sbrk(0), (void *)-1); break;1031		CASE_TEST(sbrk);              if ((p1 = p2 = sbrk(4096)) != (void *)-1) p2 = sbrk(-4096); EXPECT_SYSZR(has_brk, (p2 == (void *)-1) || p2 == p1); break;1032		CASE_TEST(brk);               EXPECT_SYSZR(has_brk, brk(sbrk(0))); break;1033		CASE_TEST(chdir_root);        EXPECT_SYSZR(1, chdir("/")); chdir(getenv("PWD")); break;1034		CASE_TEST(chdir_dot);         EXPECT_SYSZR(1, chdir(".")); break;1035		CASE_TEST(chdir_blah);        EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;1036		CASE_TEST(chmod_argv0);       EXPECT_SYSZR(1, chmod(argv0, 0555)); break;1037		CASE_TEST(chmod_self);        EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;1038		CASE_TEST(chown_self);        EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;1039		CASE_TEST(chroot_root);       EXPECT_SYSZR(euid0, chroot("/")); break;1040		CASE_TEST(chroot_blah);       EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;1041		CASE_TEST(chroot_exe);        EXPECT_SYSER(1, chroot(argv0), -1, ENOTDIR); break;1042		CASE_TEST(close_m1);          EXPECT_SYSER(1, close(-1), -1, EBADF); break;1043		CASE_TEST(close_dup);         EXPECT_SYSZR(1, close(dup(0))); break;1044		CASE_TEST(dup_0);             tmp = dup(0);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;1045		CASE_TEST(dup_m1);            tmp = dup(-1); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;1046		CASE_TEST(dup2_0);            tmp = dup2(0, 100);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;1047		CASE_TEST(dup2_m1);           tmp = dup2(-1, 100); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;1048		CASE_TEST(dup3_0);            tmp = dup3(0, 100, 0);  EXPECT_SYSNE(1, tmp, -1); close(tmp); break;1049		CASE_TEST(dup3_m1);           tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;1050		CASE_TEST(execve_root);       EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break;1051		CASE_TEST(fork);              EXPECT_SYSZR(1, test_fork()); break;1052		CASE_TEST(getdents64_root);   EXPECT_SYSNE(1, test_getdents64("/"), -1); break;1053		CASE_TEST(getdents64_null);   EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;1054		CASE_TEST(gettimeofday_tv);   EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break;1055		CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break;1056		CASE_TEST(getpagesize);       EXPECT_SYSZR(1, test_getpagesize()); break;1057		CASE_TEST(ioctl_tiocinq);     EXPECT_SYSZR(1, ioctl(0, TIOCINQ, &tmp)); break;1058		CASE_TEST(link_root1);        EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;1059		CASE_TEST(link_blah);         EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break;1060		CASE_TEST(link_dir);          EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break;1061		CASE_TEST(link_cross);        EXPECT_SYSER(proc, link("/proc/self/cmdline", "/blah"), -1, EXDEV); break;1062		CASE_TEST(lseek_m1);          EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;1063		CASE_TEST(lseek_0);           EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;1064		CASE_TEST(mkdir_root);        EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;1065		CASE_TEST(mmap_bad);          EXPECT_PTRER(1, mmap(NULL, 0, PROT_READ, MAP_PRIVATE, 0, 0), MAP_FAILED, EINVAL); break;1066		CASE_TEST(munmap_bad);        EXPECT_SYSER(1, munmap(NULL, 0), -1, EINVAL); break;1067		CASE_TEST(mmap_munmap_good);  EXPECT_SYSZR(1, test_mmap_munmap()); break;1068		CASE_TEST(open_tty);          EXPECT_SYSNE(1, tmp = open("/dev/null", 0), -1); if (tmp != -1) close(tmp); break;1069		CASE_TEST(open_blah);         EXPECT_SYSER(1, tmp = open("/proc/self/blah", 0), -1, ENOENT); if (tmp != -1) close(tmp); break;1070		CASE_TEST(pipe);              EXPECT_SYSZR(1, test_pipe()); break;1071		CASE_TEST(poll_null);         EXPECT_SYSZR(1, poll(NULL, 0, 0)); break;1072		CASE_TEST(poll_stdout);       EXPECT_SYSNE(1, ({ struct pollfd fds = { 1, POLLOUT, 0}; poll(&fds, 1, 0); }), -1); break;1073		CASE_TEST(poll_fault);        EXPECT_SYSER(1, poll(NULL, 1, 0), -1, EFAULT); break;1074		CASE_TEST(prctl);             EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;1075		CASE_TEST(read_badf);         EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;1076		CASE_TEST(rlimit);            EXPECT_SYSZR(1, test_rlimit()); break;1077		CASE_TEST(rmdir_blah);        EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break;1078		CASE_TEST(sched_yield);       EXPECT_SYSZR(1, sched_yield()); break;1079		CASE_TEST(select_null);       EXPECT_SYSZR(1, ({ struct timeval tv = { 0 }; select(0, NULL, NULL, NULL, &tv); })); break;1080		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;1081		CASE_TEST(select_fault);      EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;1082		CASE_TEST(stat_blah);         EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;1083		CASE_TEST(stat_fault);        EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;1084		CASE_TEST(stat_timestamps);   EXPECT_SYSZR(1, test_stat_timestamps()); break;1085		CASE_TEST(symlink_root);      EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;1086		CASE_TEST(uname);             EXPECT_SYSZR(proc, test_uname()); break;1087		CASE_TEST(uname_fault);       EXPECT_SYSER(1, uname(NULL), -1, EFAULT); break;1088		CASE_TEST(unlink_root);       EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;1089		CASE_TEST(unlink_blah);       EXPECT_SYSER(1, unlink("/proc/self/blah"), -1, ENOENT); break;1090		CASE_TEST(wait_child);        EXPECT_SYSER(1, wait(&tmp), -1, ECHILD); break;1091		CASE_TEST(waitpid_min);       EXPECT_SYSER(1, waitpid(INT_MIN, &tmp, WNOHANG), -1, ESRCH); break;1092		CASE_TEST(waitpid_child);     EXPECT_SYSER(1, waitpid(getpid(), &tmp, WNOHANG), -1, ECHILD); break;1093		CASE_TEST(write_badf);        EXPECT_SYSER(1, write(-1, &tmp, 1), -1, EBADF); break;1094		CASE_TEST(write_zero);        EXPECT_SYSZR(1, write(1, &tmp, 0)); break;1095		CASE_TEST(syscall_noargs);    EXPECT_SYSEQ(1, syscall(__NR_getpid), getpid()); break;1096		CASE_TEST(syscall_args);      EXPECT_SYSER(1, syscall(__NR_statx, 0, NULL, 0, 0, NULL), -1, EFAULT); break;1097		case __LINE__:1098			return ret; /* must be last */1099		/* note: do not set any defaults so as to permit holes above */1100		}1101	}1102	return ret;1103}1104 1105int run_stdlib(int min, int max)1106{1107	int test;1108	int ret = 0;1109 1110	for (test = min; test >= 0 && test <= max; test++) {1111		int llen = 0; /* line length */1112 1113		/* For functions that take a long buffer, like strlcat()1114		 * Add some more chars after the \0, to test functions that overwrite the buffer set1115		 * the \0 at the exact right position.1116		 */1117		char buf[10] = "test123456";1118		buf[4] = '\0';1119 1120 1121		/* avoid leaving empty lines below, this will insert holes into1122		 * test numbers.1123		 */1124		switch (test + __LINE__ + 1) {1125		CASE_TEST(getenv_TERM);        EXPECT_STRNZ(1, getenv("TERM")); break;1126		CASE_TEST(getenv_blah);        EXPECT_STRZR(1, getenv("blah")); break;1127		CASE_TEST(setcmp_blah_blah);   EXPECT_EQ(1, strcmp("blah", "blah"), 0); break;1128		CASE_TEST(setcmp_blah_blah2);  EXPECT_NE(1, strcmp("blah", "blah2"), 0); break;1129		CASE_TEST(setncmp_blah_blah);  EXPECT_EQ(1, strncmp("blah", "blah", 10), 0); break;1130		CASE_TEST(setncmp_blah_blah4); EXPECT_EQ(1, strncmp("blah", "blah4", 4), 0); break;1131		CASE_TEST(setncmp_blah_blah5); EXPECT_NE(1, strncmp("blah", "blah5", 5), 0); break;1132		CASE_TEST(setncmp_blah_blah6); EXPECT_NE(1, strncmp("blah", "blah6", 6), 0); break;1133		CASE_TEST(strchr_foobar_o);    EXPECT_STREQ(1, strchr("foobar", 'o'), "oobar"); break;1134		CASE_TEST(strchr_foobar_z);    EXPECT_STRZR(1, strchr("foobar", 'z')); break;1135		CASE_TEST(strrchr_foobar_o);   EXPECT_STREQ(1, strrchr("foobar", 'o'), "obar"); break;1136		CASE_TEST(strrchr_foobar_z);   EXPECT_STRZR(1, strrchr("foobar", 'z')); break;1137		CASE_TEST(strlcat_0);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 0), buf, 3, "test"); break;1138		CASE_TEST(strlcat_1);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 1), buf, 4, "test"); break;1139		CASE_TEST(strlcat_5);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 5), buf, 7, "test"); break;1140		CASE_TEST(strlcat_6);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 6), buf, 7, "testb"); break;1141		CASE_TEST(strlcat_7);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 7), buf, 7, "testba"); break;1142		CASE_TEST(strlcat_8);          EXPECT_STRBUFEQ(is_nolibc, strlcat(buf, "bar", 8), buf, 7, "testbar"); break;1143		CASE_TEST(strlcpy_0);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 0), buf, 3, "test"); break;1144		CASE_TEST(strlcpy_1);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 1), buf, 3, ""); break;1145		CASE_TEST(strlcpy_2);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 2), buf, 3, "b"); break;1146		CASE_TEST(strlcpy_3);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 3), buf, 3, "ba"); break;1147		CASE_TEST(strlcpy_4);          EXPECT_STRBUFEQ(is_nolibc, strlcpy(buf, "bar", 4), buf, 3, "bar"); break;1148		CASE_TEST(memcmp_20_20);       EXPECT_EQ(1, memcmp("aaa\x20", "aaa\x20", 4), 0); break;1149		CASE_TEST(memcmp_20_60);       EXPECT_LT(1, memcmp("aaa\x20", "aaa\x60", 4), 0); break;1150		CASE_TEST(memcmp_60_20);       EXPECT_GT(1, memcmp("aaa\x60", "aaa\x20", 4), 0); break;1151		CASE_TEST(memcmp_20_e0);       EXPECT_LT(1, memcmp("aaa\x20", "aaa\xe0", 4), 0); break;1152		CASE_TEST(memcmp_e0_20);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x20", 4), 0); break;1153		CASE_TEST(memcmp_80_e0);       EXPECT_LT(1, memcmp("aaa\x80", "aaa\xe0", 4), 0); break;1154		CASE_TEST(memcmp_e0_80);       EXPECT_GT(1, memcmp("aaa\xe0", "aaa\x80", 4), 0); break;1155		CASE_TEST(limit_int8_max);          EXPECT_EQ(1, INT8_MAX,         (int8_t)          0x7f); break;1156		CASE_TEST(limit_int8_min);          EXPECT_EQ(1, INT8_MIN,         (int8_t)          0x80); break;1157		CASE_TEST(limit_uint8_max);         EXPECT_EQ(1, UINT8_MAX,        (uint8_t)         0xff); break;1158		CASE_TEST(limit_int16_max);         EXPECT_EQ(1, INT16_MAX,        (int16_t)         0x7fff); break;1159		CASE_TEST(limit_int16_min);         EXPECT_EQ(1, INT16_MIN,        (int16_t)         0x8000); break;1160		CASE_TEST(limit_uint16_max);        EXPECT_EQ(1, UINT16_MAX,       (uint16_t)        0xffff); break;1161		CASE_TEST(limit_int32_max);         EXPECT_EQ(1, INT32_MAX,        (int32_t)         0x7fffffff); break;1162		CASE_TEST(limit_int32_min);         EXPECT_EQ(1, INT32_MIN,        (int32_t)         0x80000000); break;1163		CASE_TEST(limit_uint32_max);        EXPECT_EQ(1, UINT32_MAX,       (uint32_t)        0xffffffff); break;1164		CASE_TEST(limit_int64_max);         EXPECT_EQ(1, INT64_MAX,        (int64_t)         0x7fffffffffffffff); break;1165		CASE_TEST(limit_int64_min);         EXPECT_EQ(1, INT64_MIN,        (int64_t)         0x8000000000000000); break;1166		CASE_TEST(limit_uint64_max);        EXPECT_EQ(1, UINT64_MAX,       (uint64_t)        0xffffffffffffffff); break;1167		CASE_TEST(limit_int_least8_max);    EXPECT_EQ(1, INT_LEAST8_MAX,   (int_least8_t)    0x7f); break;1168		CASE_TEST(limit_int_least8_min);    EXPECT_EQ(1, INT_LEAST8_MIN,   (int_least8_t)    0x80); break;1169		CASE_TEST(limit_uint_least8_max);   EXPECT_EQ(1, UINT_LEAST8_MAX,  (uint_least8_t)   0xff); break;1170		CASE_TEST(limit_int_least16_max);   EXPECT_EQ(1, INT_LEAST16_MAX,  (int_least16_t)   0x7fff); break;1171		CASE_TEST(limit_int_least16_min);   EXPECT_EQ(1, INT_LEAST16_MIN,  (int_least16_t)   0x8000); break;1172		CASE_TEST(limit_uint_least16_max);  EXPECT_EQ(1, UINT_LEAST16_MAX, (uint_least16_t)  0xffff); break;1173		CASE_TEST(limit_int_least32_max);   EXPECT_EQ(1, INT_LEAST32_MAX,  (int_least32_t)   0x7fffffff); break;1174		CASE_TEST(limit_int_least32_min);   EXPECT_EQ(1, INT_LEAST32_MIN,  (int_least32_t)   0x80000000); break;1175		CASE_TEST(limit_uint_least32_max);  EXPECT_EQ(1, UINT_LEAST32_MAX, (uint_least32_t)  0xffffffffU); break;1176		CASE_TEST(limit_int_least64_min);   EXPECT_EQ(1, INT_LEAST64_MIN,  (int_least64_t)   0x8000000000000000LL); break;1177		CASE_TEST(limit_int_least64_max);   EXPECT_EQ(1, INT_LEAST64_MAX,  (int_least64_t)   0x7fffffffffffffffLL); break;1178		CASE_TEST(limit_uint_least64_max);  EXPECT_EQ(1, UINT_LEAST64_MAX, (uint_least64_t)  0xffffffffffffffffULL); break;1179		CASE_TEST(limit_int_fast8_max);     EXPECT_EQ(1, INT_FAST8_MAX,    (int_fast8_t)     0x7f); break;1180		CASE_TEST(limit_int_fast8_min);     EXPECT_EQ(1, INT_FAST8_MIN,    (int_fast8_t)     0x80); break;1181		CASE_TEST(limit_uint_fast8_max);    EXPECT_EQ(1, UINT_FAST8_MAX,   (uint_fast8_t)    0xff); break;1182		CASE_TEST(limit_int_fast16_min);    EXPECT_EQ(1, INT_FAST16_MIN,   (int_fast16_t)    SINT_MIN_OF_TYPE(int_fast16_t)); break;1183		CASE_TEST(limit_int_fast16_max);    EXPECT_EQ(1, INT_FAST16_MAX,   (int_fast16_t)    SINT_MAX_OF_TYPE(int_fast16_t)); break;1184		CASE_TEST(limit_uint_fast16_max);   EXPECT_EQ(1, UINT_FAST16_MAX,  (uint_fast16_t)   UINTPTR_MAX); break;1185		CASE_TEST(limit_int_fast32_min);    EXPECT_EQ(1, INT_FAST32_MIN,   (int_fast32_t)    SINT_MIN_OF_TYPE(int_fast32_t)); break;1186		CASE_TEST(limit_int_fast32_max);    EXPECT_EQ(1, INT_FAST32_MAX,   (int_fast32_t)    SINT_MAX_OF_TYPE(int_fast32_t)); break;1187		CASE_TEST(limit_uint_fast32_max);   EXPECT_EQ(1, UINT_FAST32_MAX,  (uint_fast32_t)   UINTPTR_MAX); break;1188		CASE_TEST(limit_int_fast64_min);    EXPECT_EQ(1, INT_FAST64_MIN,   (int_fast64_t)    INT64_MIN); break;1189		CASE_TEST(limit_int_fast64_max);    EXPECT_EQ(1, INT_FAST64_MAX,   (int_fast64_t)    INT64_MAX); break;1190		CASE_TEST(limit_uint_fast64_max);   EXPECT_EQ(1, UINT_FAST64_MAX,  (uint_fast64_t)   UINT64_MAX); break;1191		CASE_TEST(sizeof_long_sane);        EXPECT_EQ(1, sizeof(long) == 8 || sizeof(long) == 4, 1); break;1192		CASE_TEST(limit_intptr_min);        EXPECT_EQ(1, INTPTR_MIN,  sizeof(long) == 8 ? (intptr_t)  0x8000000000000000LL  : (intptr_t)  0x80000000); break;1193		CASE_TEST(limit_intptr_max);        EXPECT_EQ(1, INTPTR_MAX,  sizeof(long) == 8 ? (intptr_t)  0x7fffffffffffffffLL  : (intptr_t)  0x7fffffff); break;1194		CASE_TEST(limit_uintptr_max);       EXPECT_EQ(1, UINTPTR_MAX, sizeof(long) == 8 ? (uintptr_t) 0xffffffffffffffffULL : (uintptr_t) 0xffffffffU); break;1195		CASE_TEST(limit_ptrdiff_min);       EXPECT_EQ(1, PTRDIFF_MIN, sizeof(long) == 8 ? (ptrdiff_t) 0x8000000000000000LL  : (ptrdiff_t) 0x80000000); break;1196		CASE_TEST(limit_ptrdiff_max);       EXPECT_EQ(1, PTRDIFF_MAX, sizeof(long) == 8 ? (ptrdiff_t) 0x7fffffffffffffffLL  : (ptrdiff_t) 0x7fffffff); break;1197		CASE_TEST(limit_size_max);          EXPECT_EQ(1, SIZE_MAX,    sizeof(long) == 8 ? (size_t)    0xffffffffffffffffULL : (size_t)    0xffffffffU); break;1198		CASE_TEST(strtol_simple);           EXPECT_STRTOX(1, strtol, "35", 10, 35, -1, 0); break;1199		CASE_TEST(strtol_positive);         EXPECT_STRTOX(1, strtol, "+35", 10, 35, -1, 0); break;1200		CASE_TEST(strtol_negative);         EXPECT_STRTOX(1, strtol, "-35", 10, -35, -1, 0); break;1201		CASE_TEST(strtol_hex_auto);         EXPECT_STRTOX(1, strtol, "0xFF", 0, 255, -1, 0); break;1202		CASE_TEST(strtol_base36);           EXPECT_STRTOX(1, strtol, "12yZ", 36, 50507, -1, 0); break;1203		CASE_TEST(strtol_cutoff);           EXPECT_STRTOX(1, strtol, "1234567890", 8, 342391, 7, 0); break;1204		CASE_TEST(strtol_octal_auto);       EXPECT_STRTOX(1, strtol, "011", 0, 9, -1, 0); break;1205		CASE_TEST(strtol_hex_00);           EXPECT_STRTOX(1, strtol, "0x00", 16, 0, -1, 0); break;1206		CASE_TEST(strtol_hex_FF);           EXPECT_STRTOX(1, strtol, "FF", 16, 255, -1, 0); break;1207		CASE_TEST(strtol_hex_ff);           EXPECT_STRTOX(1, strtol, "ff", 16, 255, -1, 0); break;1208		CASE_TEST(strtol_hex_prefix);       EXPECT_STRTOX(1, strtol, "0xFF", 16, 255, -1, 0); break;1209		CASE_TEST(strtol_trailer);          EXPECT_STRTOX(1, strtol, "35foo", 10, 35, 2, 0); break;1210		CASE_TEST(strtol_overflow);         EXPECT_STRTOX(1, strtol, "0x8000000000000000", 16, LONG_MAX, -1, ERANGE); break;1211		CASE_TEST(strtol_underflow);        EXPECT_STRTOX(1, strtol, "-0x8000000000000001", 16, LONG_MIN, -1, ERANGE); break;1212		CASE_TEST(strtoul_negative);        EXPECT_STRTOX(1, strtoul, "-0x1", 16, ULONG_MAX, 4, 0); break;1213		CASE_TEST(strtoul_overflow);        EXPECT_STRTOX(1, strtoul, "0x10000000000000000", 16, ULONG_MAX, -1, ERANGE); break;1214		CASE_TEST(strerror_success);        EXPECT_STREQ(is_nolibc, strerror(0), "errno=0"); break;1215		CASE_TEST(strerror_EINVAL);         EXPECT_STREQ(is_nolibc, strerror(EINVAL), "errno=22"); break;1216		CASE_TEST(strerror_int_max);        EXPECT_STREQ(is_nolibc, strerror(INT_MAX), "errno=2147483647"); break;1217		CASE_TEST(strerror_int_min);        EXPECT_STREQ(is_nolibc, strerror(INT_MIN), "errno=-2147483648"); break;1218 1219		case __LINE__:1220			return ret; /* must be last */1221		/* note: do not set any defaults so as to permit holes above */1222		}1223	}1224	return ret;1225}1226 1227#define EXPECT_VFPRINTF(c, expected, fmt, ...)				\1228	ret += expect_vfprintf(llen, c, expected, fmt, ##__VA_ARGS__)1229 1230static int expect_vfprintf(int llen, int c, const char *expected, const char *fmt, ...)1231{1232	int ret, fd;1233	ssize_t w, r;1234	char buf[100];1235	FILE *memfile;1236	va_list args;1237 1238	fd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR, 0600);1239	if (fd == -1) {1240		result(llen, SKIPPED);1241		return 0;1242	}1243 1244	memfile = fdopen(fd, "w+");1245	if (!memfile) {1246		result(llen, FAIL);1247		return 1;1248	}1249 1250	va_start(args, fmt);1251	w = vfprintf(memfile, fmt, args);1252	va_end(args);1253 1254	if (w != c) {1255		llen += printf(" written(%d) != %d", (int)w, c);1256		result(llen, FAIL);1257		return 1;1258	}1259 1260	fflush(memfile);1261	lseek(fd, 0, SEEK_SET);1262 1263	r = read(fd, buf, sizeof(buf) - 1);1264 1265	fclose(memfile);1266 1267	if (r != w) {1268		llen += printf(" written(%d) != read(%d)", (int)w, (int)r);1269		result(llen, FAIL);1270		return 1;1271	}1272 1273	buf[r] = '\0';1274	llen += printf(" \"%s\" = \"%s\"", expected, buf);1275	ret = strncmp(expected, buf, c);1276 1277	result(llen, ret ? FAIL : OK);1278	return ret;1279}1280 1281static int run_vfprintf(int min, int max)1282{1283	int test;1284	int ret = 0;1285 1286	for (test = min; test >= 0 && test <= max; test++) {1287		int llen = 0; /* line length */1288 1289		/* avoid leaving empty lines below, this will insert holes into1290		 * test numbers.1291		 */1292		switch (test + __LINE__ + 1) {1293		CASE_TEST(empty);        EXPECT_VFPRINTF(0, "", ""); break;1294		CASE_TEST(simple);       EXPECT_VFPRINTF(3, "foo", "foo"); break;1295		CASE_TEST(string);       EXPECT_VFPRINTF(3, "foo", "%s", "foo"); break;1296		CASE_TEST(number);       EXPECT_VFPRINTF(4, "1234", "%d", 1234); break;1297		CASE_TEST(negnumber);    EXPECT_VFPRINTF(5, "-1234", "%d", -1234); break;1298		CASE_TEST(unsigned);     EXPECT_VFPRINTF(5, "12345", "%u", 12345); break;1299		CASE_TEST(char);         EXPECT_VFPRINTF(1, "c", "%c", 'c'); break;1300		CASE_TEST(hex);          EXPECT_VFPRINTF(1, "f", "%x", 0xf); break;1301		CASE_TEST(pointer);      EXPECT_VFPRINTF(3, "0x1", "%p", (void *) 0x1); break;1302		case __LINE__:1303			return ret; /* must be last */1304		/* note: do not set any defaults so as to permit holes above */1305		}1306	}1307	return ret;1308}1309 1310static int smash_stack(void)1311{1312	char buf[100];1313	volatile char *ptr = buf;1314	size_t i;1315 1316	for (i = 0; i < 200; i++)1317		ptr[i] = 'P';1318 1319	return 1;1320}1321 1322static int run_protection(int min __attribute__((unused)),1323			  int max __attribute__((unused)))1324{1325	pid_t pid;1326	int llen = 0, status;1327	struct rlimit rlimit = { 0, 0 };1328 1329	llen += printf("0 -fstackprotector ");1330 1331#if !defined(_NOLIBC_STACKPROTECTOR)1332	llen += printf("not supported");1333	result(llen, SKIPPED);1334	return 0;1335#endif1336 1337#if defined(_NOLIBC_STACKPROTECTOR)1338	if (!__stack_chk_guard) {1339		llen += printf("__stack_chk_guard not initialized");1340		result(llen, FAIL);1341		return 1;1342	}1343#endif1344 1345	pid = -1;1346	pid = fork();1347 1348	switch (pid) {1349	case -1:1350		llen += printf("fork()");1351		result(llen, FAIL);1352		return 1;1353 1354	case 0:1355		close(STDOUT_FILENO);1356		close(STDERR_FILENO);1357 1358		prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);1359		setrlimit(RLIMIT_CORE, &rlimit);1360		smash_stack();1361		return 1;1362 1363	default:1364		pid = waitpid(pid, &status, 0);1365 1366		if (pid == -1 || !WIFSIGNALED(status) || WTERMSIG(status) != SIGABRT) {1367			llen += printf("waitpid()");1368			result(llen, FAIL);1369			return 1;1370		}1371		result(llen, OK);1372		return 0;1373	}1374}1375 1376/* prepare what needs to be prepared for pid 1 (stdio, /dev, /proc, etc) */1377int prepare(void)1378{1379	struct stat stat_buf;1380 1381	/* It's possible that /dev doesn't even exist or was not mounted, so1382	 * we'll try to create it, mount it, or create minimal entries into it.1383	 * We want at least /dev/null and /dev/console.1384	 */1385	if (stat("/dev/.", &stat_buf) == 0 || mkdir("/dev", 0755) == 0) {1386		if (stat("/dev/console", &stat_buf) != 0 ||1387		    stat("/dev/null", &stat_buf) != 0 ||1388		    stat("/dev/zero", &stat_buf) != 0) {1389			/* try devtmpfs first, otherwise fall back to manual creation */1390			if (mount("/dev", "/dev", "devtmpfs", 0, 0) != 0) {1391				mknod("/dev/console", 0600 | S_IFCHR, makedev(5, 1));1392				mknod("/dev/null",    0666 | S_IFCHR, makedev(1, 3));1393				mknod("/dev/zero",    0666 | S_IFCHR, makedev(1, 5));1394			}1395		}1396	}1397 1398	/* If no /dev/console was found before calling init, stdio is closed so1399	 * we need to reopen it from /dev/console. If it failed above, it will1400	 * still fail here and we cannot emit a message anyway.1401	 */1402	if (close(dup(1)) == -1) {1403		int fd = open("/dev/console", O_RDWR);1404 1405		if (fd >= 0) {1406			if (fd != 0)1407				dup2(fd, 0);1408			if (fd != 1)1409				dup2(fd, 1);1410			if (fd != 2)1411				dup2(fd, 2);1412			if (fd > 2)1413				close(fd);1414			puts("\nSuccessfully reopened /dev/console.");1415		}1416	}1417 1418	/* try to mount /proc if not mounted. Silently fail otherwise */1419	if (stat("/proc/.", &stat_buf) == 0 || mkdir("/proc", 0755) == 0) {1420		if (stat("/proc/self", &stat_buf) != 0) {1421			/* If not mountable, remove /proc completely to avoid misuse */1422			if (mount("none", "/proc", "proc", 0, 0) != 0)1423				rmdir("/proc");1424		}1425	}1426 1427	/* some tests rely on a writable /tmp */1428	mkdir("/tmp", 0755);1429 1430	return 0;1431}1432 1433/* This is the definition of known test names, with their functions */1434static const struct test test_names[] = {1435	/* add new tests here */1436	{ .name = "startup",    .func = run_startup    },1437	{ .name = "syscall",    .func = run_syscall    },1438	{ .name = "stdlib",     .func = run_stdlib     },1439	{ .name = "vfprintf",   .func = run_vfprintf   },1440	{ .name = "protection", .func = run_protection },1441	{ 0 }1442};1443 1444static int is_setting_valid(char *test)1445{1446	int idx, len, test_len, valid = 0;1447	char delimiter;1448 1449	if (!test)1450		return valid;1451 1452	test_len = strlen(test);1453 1454	for (idx = 0; test_names[idx].name; idx++) {1455		len = strlen(test_names[idx].name);1456		if (test_len < len)1457			continue;1458 1459		if (strncmp(test, test_names[idx].name, len) != 0)1460			continue;1461 1462		delimiter = test[len];1463		if (delimiter != ':' && delimiter != ',' && delimiter != '\0')1464			continue;1465 1466		valid = 1;1467		break;1468	}1469 1470	return valid;1471}1472 1473int main(int argc, char **argv, char **envp)1474{1475	int min = 0;1476	int max = INT_MAX;1477	int ret = 0;1478	int err;1479	int idx;1480	char *test;1481 1482	argv0 = argv[0];1483	test_argc = argc;1484	test_argv = argv;1485	test_envp = envp;1486 1487	/* when called as init, it's possible that no console was opened, for1488	 * example if no /dev file system was provided. We'll check that fd#11489	 * was opened, and if not we'll attempt to create and open /dev/console1490	 * and /dev/null that we'll use for later tests.1491	 */1492	if (getpid() == 1)1493		prepare();1494 1495	/* the definition of a series of tests comes from either argv[1] or the1496	 * "NOLIBC_TEST" environment variable. It's made of a comma-delimited1497	 * series of test names and optional ranges:1498	 *    syscall:5-15[:.*],stdlib:8-101499	 */1500	test = argv[1];1501	if (!is_setting_valid(test))1502		test = getenv("NOLIBC_TEST");1503 1504	if (is_setting_valid(test)) {1505		char *comma, *colon, *dash, *value;1506 1507		do {1508			comma = strchr(test, ',');1509			if (comma)1510				*(comma++) = '\0';1511 1512			colon = strchr(test, ':');1513			if (colon)1514				*(colon++) = '\0';1515 1516			for (idx = 0; test_names[idx].name; idx++) {1517				if (strcmp(test, test_names[idx].name) == 0)1518					break;1519			}1520 1521			if (test_names[idx].name) {1522				/* The test was named, it will be called at least1523				 * once. We may have an optional range at <colon>1524				 * here, which defaults to the full range.1525				 */1526				do {1527					min = 0; max = INT_MAX;1528					value = colon;1529					if (value && *value) {1530						colon = strchr(value, ':');1531						if (colon)1532							*(colon++) = '\0';1533 1534						dash = strchr(value, '-');1535						if (dash)1536							*(dash++) = '\0';1537 1538						/* support :val: :min-max: :min-: :-max: */1539						if (*value)1540							min = atoi(value);1541						if (!dash)1542							max = min;1543						else if (*dash)1544							max = atoi(dash);1545 1546						value = colon;1547					}1548 1549					/* now's time to call the test */1550					printf("Running test '%s'\n", test_names[idx].name);1551					err = test_names[idx].func(min, max);1552					ret += err;1553					printf("Errors during this test: %d\n\n", err);1554				} while (colon && *colon);1555			} else1556				printf("Ignoring unknown test name '%s'\n", test);1557 1558			test = comma;1559		} while (test && *test);1560	} else {1561		/* no test mentioned, run everything */1562		for (idx = 0; test_names[idx].name; idx++) {1563			printf("Running test '%s'\n", test_names[idx].name);1564			err = test_names[idx].func(min, max);1565			ret += err;1566			printf("Errors during this test: %d\n\n", err);1567		}1568	}1569 1570	printf("Total number of errors: %d\n", ret);1571 1572	if (getpid() == 1) {1573		/* we're running as init, there's no other process on the1574		 * system, thus likely started from a VM for a quick check.1575		 * Exiting will provoke a kernel panic that may be reported1576		 * as an error by Qemu or the hypervisor, while stopping1577		 * cleanly will often be reported as a success. This allows1578		 * to use the output of this program for bisecting kernels.1579		 */1580		printf("Leaving init with final status: %d\n", !!ret);1581		if (ret == 0)1582			reboot(RB_POWER_OFF);1583#if defined(__x86_64__)1584		/* QEMU started with "-device isa-debug-exit -no-reboot" will1585		 * exit with status code 2N+1 when N is written to 0x501. We1586		 * hard-code the syscall here as it's arch-dependent.1587		 */1588		else if (syscall(__NR_ioperm, 0x501, 1, 1) == 0)1589			__asm__ volatile ("outb %%al, %%dx" :: "d"(0x501), "a"(0));1590		/* if it does nothing, fall back to the regular panic */1591#endif1592	}1593 1594	printf("Exiting with status %d\n", !!ret);1595	return !!ret;1596}1597