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