2023-06-29 23:24:49

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 00/15] allow run with minimal kernel config

Willy, Thomas

This is v2 to allow run with minimal kernel config, see v1 [1].

It mainly applied the suggestions from Thomas. It is based on our
previous v5 sysret helper series [2] and Thomas' chmod_net removal
patchset [3].

Now, a test report on arm/vexpress-a9 without procfs, shmem, tmpfs, net
and memfd_create looks like:

LOG: testing report for arm/vexpress-a9:

14 chmod_net [SKIPPED]
15 chmod_self [SKIPPED]
17 chown_self [SKIPPED]
41 link_cross [SKIPPED]
0 -fstackprotector not supported [SKIPPED]

139 test(s) passed, 5 skipped, 0 failed.
See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log

LOG: testing summary:

arch/board | result
------------|------------
arm/vexpress-a9 | 139 test(s) passed, 5 skipped, 0 failed. See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log

Changes from v1 --> v2:

* selftests/nolibc: stat_fault: silence NULL argument warning with glibc
selftests/nolibc: gettid: restore for glibc and musl
selftests/nolibc: add _LARGEFILE64_SOURCE for musl
selftests/nolibc: add a new rmdir() test case
selftests/nolibc: fix up failures when CONFIG_PROC_FS=n

The same as v1, only a few of commit message changes.

* selftests/nolibc: fix up int_fast16/32_t test cases for musl

Applied the method suggested by Thomas, two new macros are added to
get SINT_MAX_OF_TYPE(type) and SINT_MIN_OF_TYPE(type).

* selftests/nolibc: fix up kernel parameters support

After discuss with Thomas and with more tests, both of argv[1] and
NOLIBC_TEST environment variable should be verified to support
such kernel parameters:

NOLIBC_TEST=syscall
noapic NOLIBC_TEST=syscall
noapic

* selftests/nolibc: stat_timestamps: remove procfs dependency

Add '/init' and '/' for !procfs, don't skip it.

* selftests/nolibc: link_cross: use /proc/self/cmdline

Use /proc/self/cmdline instead of /proc/self/net, the ramfs based
/tmp/file doesn't work as expected (not really crossdev).

* tools/nolibc: add rmdir() support

Now, rebased on __sysret() from sysret helper patchset [2].

* selftests/nolibc: prepare /tmp for tmpfs or ramfs

Removed the hugetlbfs prepare part, not really required.

Don't remove /tmp and reserve it to use ramfs as tmpfs.

* selftests/nolibc: add common get_tmpfile()
selftests/nolibc: rename chroot_exe to chroot_tmpfile

Some cleanups.

* selftests/nolibc: add chmod_tmpfile test

To avoid conflict with Thomas' chmod_net removal patch [3], a new
chmod_tmpfile is added (in v1, there is a rename patch from
chmod_net to chmod_good)

Still to avoid conflict, these two are removed in this series:

- selftests/nolibc: rename proc variable to has_proc
- selftests/nolibc: rename euid0 variable to is_root

* selftests/nolibc: vfprintf: remove MEMFD_CREATE dependency

Many checks are removed, only reserve the direct tmpfs access
version.

Best regards,
Zhangjin
---
[1]: https://lore.kernel.org/lkml/[email protected]/
[2]: https://lore.kernel.org/lkml/[email protected]/
[3]: https://lore.kernel.org/lkml/[email protected]/

Zhangjin Wu (15):
selftests/nolibc: stat_fault: silence NULL argument warning with glibc
selftests/nolibc: gettid: restore for glibc and musl
selftests/nolibc: add _LARGEFILE64_SOURCE for musl
selftests/nolibc: fix up int_fast16/32_t test cases for musl
selftests/nolibc: fix up kernel parameters support
selftests/nolibc: stat_timestamps: remove procfs dependency
selftests/nolibc: link_cross: use /proc/self/cmdline
tools/nolibc: add rmdir() support
selftests/nolibc: add a new rmdir() test case
selftests/nolibc: fix up failures when CONFIG_PROC_FS=n
selftests/nolibc: prepare /tmp for tmpfs or ramfs
selftests/nolibc: add common get_tmpfile()
selftests/nolibc: rename chroot_exe to chroot_tmpfile
selftests/nolibc: add chmod_tmpfile test
selftests/nolibc: vfprintf: remove MEMFD_CREATE dependency

tools/include/nolibc/sys.h | 22 ++++
tools/testing/selftests/nolibc/nolibc-test.c | 102 +++++++++++++++----
2 files changed, 106 insertions(+), 18 deletions(-)

--
2.25.1



2023-06-29 23:43:25

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 04/15] selftests/nolibc: fix up int_fast16/32_t test cases for musl

musl limits the fast signed int in 32bit, but glibc and nolibc don't, to
let such test cases work on musl, let's provide the type based
SINT_MAX_OF_TYPE(type) and SINT_MIN_OF_TYPE(type).

Suggested-by: Thomas Weißschuh <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]/
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 29c21880a198..96d170cc9b47 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -41,6 +41,10 @@
#endif
#endif

+/* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */
+#define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
+#define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
+
/* will be used by nolibc by getenv() */
char **environ;

@@ -819,11 +823,11 @@ int run_stdlib(int min, int max)
CASE_TEST(limit_int_fast8_max); EXPECT_EQ(1, INT_FAST8_MAX, (int_fast8_t) 0x7f); break;
CASE_TEST(limit_int_fast8_min); EXPECT_EQ(1, INT_FAST8_MIN, (int_fast8_t) 0x80); break;
CASE_TEST(limit_uint_fast8_max); EXPECT_EQ(1, UINT_FAST8_MAX, (uint_fast8_t) 0xff); break;
- CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) INTPTR_MIN); break;
- CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) INTPTR_MAX); break;
+ CASE_TEST(limit_int_fast16_min); EXPECT_EQ(1, INT_FAST16_MIN, (int_fast16_t) SINT_MIN_OF_TYPE(int_fast16_t)); break;
+ CASE_TEST(limit_int_fast16_max); EXPECT_EQ(1, INT_FAST16_MAX, (int_fast16_t) SINT_MAX_OF_TYPE(int_fast16_t)); break;
CASE_TEST(limit_uint_fast16_max); EXPECT_EQ(1, UINT_FAST16_MAX, (uint_fast16_t) UINTPTR_MAX); break;
- CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) INTPTR_MIN); break;
- CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) INTPTR_MAX); break;
+ CASE_TEST(limit_int_fast32_min); EXPECT_EQ(1, INT_FAST32_MIN, (int_fast32_t) SINT_MIN_OF_TYPE(int_fast32_t)); break;
+ CASE_TEST(limit_int_fast32_max); EXPECT_EQ(1, INT_FAST32_MAX, (int_fast32_t) SINT_MAX_OF_TYPE(int_fast32_t)); break;
CASE_TEST(limit_uint_fast32_max); EXPECT_EQ(1, UINT_FAST32_MAX, (uint_fast32_t) UINTPTR_MAX); break;
CASE_TEST(limit_int_fast64_min); EXPECT_EQ(1, INT_FAST64_MIN, (int_fast64_t) INT64_MIN); break;
CASE_TEST(limit_int_fast64_max); EXPECT_EQ(1, INT_FAST64_MAX, (int_fast64_t) INT64_MAX); break;
--
2.25.1


2023-06-29 23:43:43

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 01/15] selftests/nolibc: stat_fault: silence NULL argument warning with glibc

Use another invalid address (void *)1 instead of NULL to silence this
compile warning with glibc:

$ make libc-test
CC libc-test
nolibc-test.c: In function ‘run_syscall’:
nolibc-test.c:622:49: warning: null argument where non-null required (argument 1) [-Wnonnull]
622 | CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
| ^~~~
nolibc-test.c:304:79: note: in definition of macro ‘EXPECT_SYSER2’
304 | do { if (!cond) pad_spc(llen, 64, "[SKIPPED]\n"); else ret += expect_syserr2(expr, expret, experr1, experr2, llen); } while (0)
| ^~~~
nolibc-test.c:622:33: note: in expansion of macro ‘EXPECT_SYSER’
622 | CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index b178bfa29ad9..a2eacd6436d0 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -734,7 +734,7 @@ int run_syscall(int min, int max)
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;
CASE_TEST(select_fault); EXPECT_SYSER(1, select(1, (void *)1, NULL, NULL, 0), -1, EFAULT); break;
CASE_TEST(stat_blah); EXPECT_SYSER(1, stat("/proc/self/blah", &stat_buf), -1, ENOENT); break;
- CASE_TEST(stat_fault); EXPECT_SYSER(1, stat(NULL, &stat_buf), -1, EFAULT); break;
+ CASE_TEST(stat_fault); EXPECT_SYSER(1, stat((void *)1, &stat_buf), -1, EFAULT); break;
CASE_TEST(stat_timestamps); EXPECT_SYSZR(1, test_stat_timestamps()); break;
CASE_TEST(symlink_root); EXPECT_SYSER(1, symlink("/", "/"), -1, EEXIST); break;
CASE_TEST(unlink_root); EXPECT_SYSER(1, unlink("/"), -1, EISDIR); break;
--
2.25.1


2023-06-29 23:43:52

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 05/15] selftests/nolibc: fix up kernel parameters support

kernel parameters allow pass two types of strings, one type is like
'noapic', another type is like 'panic=5', the first type is passed as
arguments of the init program, the second type is passed as environment
variables of the init program.

when users pass kernel parameters like this:

noapic NOLIBC_TEST=syscall

our nolibc-test program will use the test setting from argv[1] and
ignore the one from NOLIBC_TEST environment variable, and at last, it
will print the following line and ignore the whole test setting.

Ignoring unknown test name 'noapic'

reversing the parsing order does solve the above issue:

test = getenv("NOLIBC_TEST");
if (test)
test = argv[1];

but it still doesn't work with such kernel parameters (without
NOLIBC_TEST environment variable):

noapic FOO=bar

To support all of the potential kernel parameters, let's verify the test
setting from both of argv[1] and NOLIBC_TEST environment variable.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 33 ++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 96d170cc9b47..223c00e83abf 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1063,6 +1063,35 @@ static const struct test test_names[] = {
{ 0 }
};

+int is_setting_valid(char *test)
+{
+ int idx, len, test_len, valid = 0;
+ char delimiter;
+
+ if (!test)
+ return valid;
+
+ test_len = strlen(test);
+
+ for (idx = 0; test_names[idx].name; idx++) {
+ len = strlen(test_names[idx].name);
+ if (test_len < len)
+ continue;
+
+ if (strncmp(test, test_names[idx].name, len) != 0)
+ continue;
+
+ delimiter = test[len];
+ if (delimiter != ':' && delimiter != ',' && delimiter != '\0')
+ continue;
+
+ valid = 1;
+ break;
+ }
+
+ return valid;
+}
+
int main(int argc, char **argv, char **envp)
{
int min = 0;
@@ -1088,10 +1117,10 @@ int main(int argc, char **argv, char **envp)
* syscall:5-15[:.*],stdlib:8-10
*/
test = argv[1];
- if (!test)
+ if (!is_setting_valid(test))
test = getenv("NOLIBC_TEST");

- if (test) {
+ if (is_setting_valid(test)) {
char *comma, *colon, *dash, *value;

do {
--
2.25.1


2023-06-29 23:44:22

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 03/15] selftests/nolibc: add _LARGEFILE64_SOURCE for musl

_GNU_SOURCE Implies _LARGEFILE64_SOURCE in glibc, but in musl, the
default configuration doesn't enable _LARGEFILE64_SOURCE.

From include/dirent.h of musl, getdents64 is provided as getdents when
_LARGEFILE64_SOURCE is defined.

#if defined(_LARGEFILE64_SOURCE)
...
#define getdents64 getdents
#endif

Let's define _LARGEFILE64_SOURCE to fix up this compile error:

tools/testing/selftests/nolibc/nolibc-test.c: In function ‘test_getdents64’:
tools/testing/selftests/nolibc/nolibc-test.c:453:8: warning: implicit declaration of function ‘getdents64’; did you mean ‘getdents’? [-Wimplicit-function-declaration]
453 | ret = getdents64(fd, (void *)buffer, sizeof(buffer));
| ^~~~~~~~~~
| getdents
/usr/bin/ld: /tmp/ccKILm5u.o: in function `test_getdents64':
nolibc-test.c:(.text+0xe3e): undefined reference to `getdents64'
collect2: error: ld returned 1 exit status

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 785b1f4cbdc5..29c21880a198 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */

#define _GNU_SOURCE
+#define _LARGEFILE64_SOURCE

/* libc-specific include files
* The program may be built in 3 ways:
--
2.25.1


2023-06-29 23:44:25

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 02/15] selftests/nolibc: gettid: restore for glibc and musl

As the gettid manpage [1] shows, glibc 2.30 has gettid support, so,
let's enable the test for glibc >= 2.30.

gettid works on musl too.

[1]: https://man7.org/linux/man-pages/man2/gettid.2.html

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index a2eacd6436d0..785b1f4cbdc5 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -659,6 +659,7 @@ int run_syscall(int min, int max)
int tmp;
int ret = 0;
void *p1, *p2;
+ int has_gettid = 1;

/* <proc> indicates whether or not /proc is mounted */
proc = stat("/proc", &stat_buf) == 0;
@@ -666,6 +667,11 @@ int run_syscall(int min, int max)
/* this will be used to skip certain tests that can't be run unprivileged */
euid0 = geteuid() == 0;

+ /* from 2.30, glibc provides gettid() */
+#if defined(__GLIBC_MINOR__) && defined(__GLIBC__)
+ has_gettid = __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 30);
+#endif
+
for (test = min; test >= 0 && test <= max; test++) {
int llen = 0; /* line length */

@@ -675,9 +681,7 @@ int run_syscall(int min, int max)
switch (test + __LINE__ + 1) {
CASE_TEST(getpid); EXPECT_SYSNE(1, getpid(), -1); break;
CASE_TEST(getppid); EXPECT_SYSNE(1, getppid(), -1); break;
-#ifdef NOLIBC
- CASE_TEST(gettid); EXPECT_SYSNE(1, gettid(), -1); break;
-#endif
+ CASE_TEST(gettid); EXPECT_SYSNE(has_gettid, gettid(), -1); break;
CASE_TEST(getpgid_self); EXPECT_SYSNE(1, getpgid(0), -1); break;
CASE_TEST(getpgid_bad); EXPECT_SYSER(1, getpgid(-1), -1, ESRCH); break;
CASE_TEST(kill_0); EXPECT_SYSZR(1, kill(getpid(), 0)); break;
--
2.25.1


2023-06-29 23:51:45

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 06/15] selftests/nolibc: stat_timestamps: remove procfs dependency

'/proc/self/' is a good path which doesn't have stale time info but it
is only available for CONFIG_PROC_FS=y.

For CONFIG_PROC_FS=n, Let's try '/init' for initramfs and '/' for the
others.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 223c00e83abf..1d2be52d44a5 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -582,7 +582,7 @@ static int test_stat_timestamps(void)
if (sizeof(st.st_atim.tv_sec) != sizeof(st.st_atime))
return 1;

- if (stat("/proc/self/", &st))
+ if (stat("/proc/self/", &st) && stat("/init", &st) && stat("/", &st))
return 1;

if (st.st_atim.tv_sec != st.st_atime || st.st_atim.tv_nsec > 1000000000)
--
2.25.1


2023-06-30 00:09:04

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 12/15] selftests/nolibc: add common get_tmpfile()

allow create and get a temporary file from tmpfs.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 8e3e2792f5e3..1002e0267515 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -54,6 +54,23 @@ struct test {
int (*func)(int min, int max); /* handler */
};

+static const char *get_tmpfile(const char *tmpfile)
+{
+ struct stat stat_buf;
+ int fd;
+
+ if (stat(tmpfile, &stat_buf) == 0)
+ return tmpfile;
+
+ fd = open(tmpfile, O_CREAT, 0600);
+ if (fd != -1) {
+ close(fd);
+ return tmpfile;
+ }
+
+ return NULL;
+}
+
#ifndef _NOLIBC_STDLIB_H
char *itoa(int i)
{
--
2.25.1


2023-06-30 00:09:07

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 07/15] selftests/nolibc: link_cross: use /proc/self/cmdline

For CONFIG_NET=n, there would be no /proc/self/net, so, use
/proc/self/cmdline instead.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 1d2be52d44a5..0bb222eaafca 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -724,7 +724,7 @@ int run_syscall(int min, int max)
CASE_TEST(link_root1); EXPECT_SYSER(1, link("/", "/"), -1, EEXIST); break;
CASE_TEST(link_blah); EXPECT_SYSER(1, link("/proc/self/blah", "/blah"), -1, ENOENT); break;
CASE_TEST(link_dir); EXPECT_SYSER(euid0, link("/", "/blah"), -1, EPERM); break;
- CASE_TEST(link_cross); EXPECT_SYSER(proc, link("/proc/self/net", "/blah"), -1, EXDEV); break;
+ CASE_TEST(link_cross); EXPECT_SYSER(proc, link("/proc/self/cmdline", "/blah"), -1, EXDEV); break;
CASE_TEST(lseek_m1); EXPECT_SYSER(1, lseek(-1, 0, SEEK_SET), -1, EBADF); break;
CASE_TEST(lseek_0); EXPECT_SYSER(1, lseek(0, 0, SEEK_SET), -1, ESPIPE); break;
CASE_TEST(mkdir_root); EXPECT_SYSER(1, mkdir("/", 0755), -1, EEXIST); break;
--
2.25.1


2023-06-30 00:09:20

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 09/15] selftests/nolibc: add a new rmdir() test case

A new rmdir_blah test case is added to remove a non-existing /blah,
which expects failure with ENOENT errno.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 0bb222eaafca..2725d3dbfaf0 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -738,6 +738,7 @@ int run_syscall(int min, int max)
CASE_TEST(poll_fault); EXPECT_SYSER(1, poll((void *)1, 1, 0), -1, EFAULT); break;
CASE_TEST(prctl); EXPECT_SYSER(1, prctl(PR_SET_NAME, (unsigned long)NULL, 0, 0, 0), -1, EFAULT); break;
CASE_TEST(read_badf); EXPECT_SYSER(1, read(-1, &tmp, 1), -1, EBADF); break;
+ CASE_TEST(rmdir_blah); EXPECT_SYSER(1, rmdir("/blah"), -1, ENOENT); break;
CASE_TEST(sched_yield); EXPECT_SYSZR(1, sched_yield()); break;
CASE_TEST(select_null); EXPECT_SYSZR(1, ({ struct timeval tv = { 0 }; select(0, NULL, NULL, NULL, &tv); })); break;
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;
--
2.25.1


2023-06-30 00:10:37

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 10/15] selftests/nolibc: fix up failures when CONFIG_PROC_FS=n

For CONFIG_PROC_FS=n, the /proc is not mountable, but the /proc
directory has been created in the prepare() stage whenever /proc is
there or not.

so, the checking of /proc in the run_syscall() stage will be always true
and at last it will fail all of the procfs dependent test cases, which
deviates from the 'cond' check design of the EXPECT_xx macros, without
procfs, these test cases should be skipped instead of failed.

To solve this issue, one method is checking /proc/self instead of /proc,
another method is removing the /proc directory completely for
CONFIG_PROC_FS=n, we apply the second method to avoid misleading the
users.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 2725d3dbfaf0..c0f5302ada5d 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1047,8 +1047,11 @@ int prepare(void)

/* try to mount /proc if not mounted. Silently fail otherwise */
if (stat("/proc/.", &stat_buf) == 0 || mkdir("/proc", 0755) == 0) {
- if (stat("/proc/self", &stat_buf) != 0)
- mount("/proc", "/proc", "proc", 0, 0);
+ if (stat("/proc/self", &stat_buf) != 0) {
+ /* If not mountable, remove /proc completely to avoid misuse */
+ if (mount("none", "/proc", "proc", 0, 0) != 0)
+ rmdir("/proc");
+ }
}

return 0;
--
2.25.1


2023-06-30 00:11:42

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 13/15] selftests/nolibc: rename chroot_exe to chroot_tmpfile

For CONFIG_PROC_FS=n, let's use tmpfs and create a tmp file for
chroot_exe test.

Since chroot_exe is mainly testing the not directory case (ENOTDIR), so,
rename it to chroot_tmpfile may be better.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 1002e0267515..2e9eaa7efa6e 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -682,6 +682,8 @@ int run_syscall(int min, int max)
int ret = 0;
void *p1, *p2;
int has_gettid = 1;
+ const char *tmpfile = get_tmpfile("/tmp/dummy");
+ int has_tmpfile = tmpfile != NULL;

/* <proc> indicates whether or not /proc is mounted */
proc = stat("/proc", &stat_buf) == 0;
@@ -720,7 +722,7 @@ int run_syscall(int min, int max)
CASE_TEST(chown_self); EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
CASE_TEST(chroot_root); EXPECT_SYSZR(euid0, chroot("/")); break;
CASE_TEST(chroot_blah); EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
- CASE_TEST(chroot_exe); EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
+ CASE_TEST(chroot_tmpfile); EXPECT_SYSER(has_tmpfile, chroot(tmpfile), -1, ENOTDIR); break;
CASE_TEST(close_m1); EXPECT_SYSER(1, close(-1), -1, EBADF); break;
CASE_TEST(close_dup); EXPECT_SYSZR(1, close(dup(0))); break;
CASE_TEST(dup_0); tmp = dup(0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
--
2.25.1


2023-06-30 00:21:14

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 08/15] tools/nolibc: add rmdir() support

a reverse operation of mkdir() is meaningful, add rmdir() here.

required by nolibc-test to remove /proc while CONFIG_PROC_FS is not
enabled.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/include/nolibc/sys.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/tools/include/nolibc/sys.h b/tools/include/nolibc/sys.h
index b6c33c40c037..7b052958e2ae 100644
--- a/tools/include/nolibc/sys.h
+++ b/tools/include/nolibc/sys.h
@@ -610,6 +610,28 @@ int mkdir(const char *path, mode_t mode)
return __sysret(sys_mkdir(path, mode));
}

+/*
+ * int rmdir(const char *path);
+ */
+
+static __attribute__((unused))
+int sys_rmdir(const char *path)
+{
+#ifdef __NR_rmdir
+ return my_syscall1(__NR_rmdir, path);
+#elif defined(__NR_unlinkat)
+ return my_syscall3(__NR_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
+#else
+ return -ENOSYS;
+#endif
+}
+
+static __attribute__((unused))
+int rmdir(const char *path)
+{
+ return __sysret(sys_rmdir(path));
+}
+

/*
* int mknod(const char *path, mode_t mode, dev_t dev);
--
2.25.1


2023-06-30 00:25:48

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 15/15] selftests/nolibc: vfprintf: remove MEMFD_CREATE dependency

The vfprintf test case require to open a temporary file to write, the
old memfd_create() method is perfect but has strong dependency on
MEMFD_CREATE and also TMPFS or HUGETLBFS (see fs/Kconfig):

config MEMFD_CREATE
def_bool TMPFS || HUGETLBFS

And from v6.2, MFD_NOEXEC_SEAL must be passed for the non-executable
memfd, otherwise, The kernel warning will be output to the test result
like this:

Running test 'vfprintf'
0 emptymemfd_create() without MFD_EXEC nor MFD_NOEXEC_SEAL, pid=1 'init'
"" = "" [OK]

To avoid such warning and also to remove the MEMFD_CREATE dependency,
let's open a file from tmpfs directly.

The /tmp directory is used to detect the existing of tmpfs, if not
there, skip instead of fail.

And further, for pid == 1, the initramfs is loaded as ramfs, which can
be used as tmpfs, so, it is able to further remove TMPFS dependency too.

Suggested-by: Thomas Weißschuh <[email protected]>
Link: https://lore.kernel.org/lkml/[email protected]
Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 0ca7d011765a..0847813d756c 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -888,10 +888,10 @@ static int expect_vfprintf(int llen, size_t c, const char *expected, const char
FILE *memfile;
va_list args;

- fd = memfd_create("vfprintf", 0);
+ fd = open("/tmp", O_TMPFILE | O_EXCL | O_RDWR, 0600);
if (fd == -1) {
- pad_spc(llen, 64, "[FAIL]\n");
- return 1;
+ pad_spc(llen, 64, "[SKIPPED]\n");
+ return 0;
}

memfile = fdopen(fd, "w+");
--
2.25.1


2023-06-30 00:26:00

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 14/15] selftests/nolibc: add chmod_tmpfile test

allow test chmod with tmpfs even when procfs is not there.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 2e9eaa7efa6e..0ca7d011765a 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -719,6 +719,7 @@ int run_syscall(int min, int max)
CASE_TEST(chdir_blah); EXPECT_SYSER(1, chdir("/blah"), -1, ENOENT); break;
CASE_TEST(chmod_net); EXPECT_SYSZR(proc, chmod("/proc/self/net", 0555)); break;
CASE_TEST(chmod_self); EXPECT_SYSER(proc, chmod("/proc/self", 0555), -1, EPERM); break;
+ CASE_TEST(chmod_tmpfile); EXPECT_SYSZR(has_tmpfile, chmod(tmpfile, 0555)); break;
CASE_TEST(chown_self); EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
CASE_TEST(chroot_root); EXPECT_SYSZR(euid0, chroot("/")); break;
CASE_TEST(chroot_blah); EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
--
2.25.1


2023-06-30 00:26:26

by Zhangjin Wu

[permalink] [raw]
Subject: [PATCH v2 11/15] selftests/nolibc: prepare /tmp for tmpfs or ramfs

Let's create a /tmp directory and mount tmpfs there, if tmpfs is not
mountable, use ramfs as tmpfs.

tmpfs will be used instead of procfs for some tests.

Signed-off-by: Zhangjin Wu <[email protected]>
---
tools/testing/selftests/nolibc/nolibc-test.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index c0f5302ada5d..8e3e2792f5e3 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -1054,6 +1054,10 @@ int prepare(void)
}
}

+ /* try to mount /tmp if not mounted, if not mountable, use ramfs as tmpfs */
+ if (stat("/tmp/.", &stat_buf) == 0 || mkdir("/tmp", 0755) == 0)
+ mount("none", "/tmp", "tmpfs", 0, 0);
+
return 0;
}

--
2.25.1


2023-06-30 09:06:10

by Thomas Weißschuh

[permalink] [raw]
Subject: Re: [PATCH v2 13/15] selftests/nolibc: rename chroot_exe to chroot_tmpfile

On 2023-06-30 08:00:28+0800, Zhangjin Wu wrote:
> For CONFIG_PROC_FS=n, let's use tmpfs and create a tmp file for
> chroot_exe test.
>
> Since chroot_exe is mainly testing the not directory case (ENOTDIR), so,
> rename it to chroot_tmpfile may be better.
>
> Signed-off-by: Zhangjin Wu <[email protected]>
> ---
> tools/testing/selftests/nolibc/nolibc-test.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index 1002e0267515..2e9eaa7efa6e 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -682,6 +682,8 @@ int run_syscall(int min, int max)
> int ret = 0;
> void *p1, *p2;
> int has_gettid = 1;
> + const char *tmpfile = get_tmpfile("/tmp/dummy");
> + int has_tmpfile = tmpfile != NULL;
>
> /* <proc> indicates whether or not /proc is mounted */
> proc = stat("/proc", &stat_buf) == 0;
> @@ -720,7 +722,7 @@ int run_syscall(int min, int max)
> CASE_TEST(chown_self); EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
> CASE_TEST(chroot_root); EXPECT_SYSZR(euid0, chroot("/")); break;
> CASE_TEST(chroot_blah); EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
> - CASE_TEST(chroot_exe); EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
> + CASE_TEST(chroot_tmpfile); EXPECT_SYSER(has_tmpfile, chroot(tmpfile), -1, ENOTDIR); break;

get_tempfile() looks really weird.
Given that the nolibc implementation of chroot() is the most trivial
imaginable in my opinion we can keep the current "chroot_exe" that is
using procfs.

> CASE_TEST(close_m1); EXPECT_SYSER(1, close(-1), -1, EBADF); break;
> CASE_TEST(close_dup); EXPECT_SYSZR(1, close(dup(0))); break;
> CASE_TEST(dup_0); tmp = dup(0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
> --
> 2.25.1
>

2023-06-30 09:07:44

by Thomas Weißschuh

[permalink] [raw]
Subject: Re: [PATCH v2 11/15] selftests/nolibc: prepare /tmp for tmpfs or ramfs

On 2023-06-30 07:52:03+0800, Zhangjin Wu wrote:
> Let's create a /tmp directory and mount tmpfs there, if tmpfs is not
> mountable, use ramfs as tmpfs.
>
> tmpfs will be used instead of procfs for some tests.
>
> Signed-off-by: Zhangjin Wu <[email protected]>
> ---
> tools/testing/selftests/nolibc/nolibc-test.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index c0f5302ada5d..8e3e2792f5e3 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> @@ -1054,6 +1054,10 @@ int prepare(void)
> }
> }
>
> + /* try to mount /tmp if not mounted, if not mountable, use ramfs as tmpfs */
> + if (stat("/tmp/.", &stat_buf) == 0 || mkdir("/tmp", 0755) == 0)
> + mount("none", "/tmp", "tmpfs", 0, 0);
> +

mkdir()
mount()

without any error checking should do the same and be easier to read.

> return 0;
> }
>
> --
> 2.25.1
>

2023-06-30 09:10:28

by Thomas Weißschuh

[permalink] [raw]
Subject: Re: [PATCH v2 00/15] allow run with minimal kernel config

On 2023-06-30 07:22:39+0800, Zhangjin Wu wrote:
> Willy, Thomas
>
> This is v2 to allow run with minimal kernel config, see v1 [1].
>
> It mainly applied the suggestions from Thomas. It is based on our
> previous v5 sysret helper series [2] and Thomas' chmod_net removal
> patchset [3].
>
> Now, a test report on arm/vexpress-a9 without procfs, shmem, tmpfs, net
> and memfd_create looks like:
>
> LOG: testing report for arm/vexpress-a9:
>
> 14 chmod_net [SKIPPED]

Shouldn't this be gone?

> 15 chmod_self [SKIPPED]
> 17 chown_self [SKIPPED]
> 41 link_cross [SKIPPED]
> 0 -fstackprotector not supported [SKIPPED]
>
> 139 test(s) passed, 5 skipped, 0 failed.
> See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log
>
> LOG: testing summary:
>
> arch/board | result
> ------------|------------
> arm/vexpress-a9 | 139 test(s) passed, 5 skipped, 0 failed. See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log

> [..]

> tools/include/nolibc/sys.h | 22 ++++
> tools/testing/selftests/nolibc/nolibc-test.c | 102 +++++++++++++++----
> 2 files changed, 106 insertions(+), 18 deletions(-)

A few nitpicks left, mentioned on the patches themselves.

In general: for the full series.

Reviewed-by: Thomas Weißschuh <[email protected]>

2023-06-30 10:53:48

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v2 11/15] selftests/nolibc: prepare /tmp for tmpfs or ramfs

Hi, Thomas

> On 2023-06-30 07:52:03+0800, Zhangjin Wu wrote:
> > Let's create a /tmp directory and mount tmpfs there, if tmpfs is not
> > mountable, use ramfs as tmpfs.
> >
> > tmpfs will be used instead of procfs for some tests.
> >
> > Signed-off-by: Zhangjin Wu <[email protected]>
> > ---
> > tools/testing/selftests/nolibc/nolibc-test.c | 4 ++++
> > 1 file changed, 4 insertions(+)
> >
> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index c0f5302ada5d..8e3e2792f5e3 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > @@ -1054,6 +1054,10 @@ int prepare(void)
> > }
> > }
> >
> > + /* try to mount /tmp if not mounted, if not mountable, use ramfs as tmpfs */
> > + if (stat("/tmp/.", &stat_buf) == 0 || mkdir("/tmp", 0755) == 0)
> > + mount("none", "/tmp", "tmpfs", 0, 0);
> > +
>
> mkdir()
> mount()
>
> without any error checking should do the same and be easier to read.
>

Yeah, will apply it, it saves a call for us.

Perhaps the other codes in prepare() can be cleaned up with the same method in the future too.

Thanks,
Zhangjin

> > return 0;
> > }
> >
> > --
> > 2.25.1
> >

2023-06-30 11:52:01

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v2 13/15] selftests/nolibc: rename chroot_exe to chroot_tmpfile

Hi, Thomas

> On 2023-06-30 08:00:28+0800, Zhangjin Wu wrote:
> > For CONFIG_PROC_FS=n, let's use tmpfs and create a tmp file for
> > chroot_exe test.
> >
> > Since chroot_exe is mainly testing the not directory case (ENOTDIR), so,
> > rename it to chroot_tmpfile may be better.
> >
> > Signed-off-by: Zhangjin Wu <[email protected]>
> > ---
> > tools/testing/selftests/nolibc/nolibc-test.c | 4 +++-
> > 1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index 1002e0267515..2e9eaa7efa6e 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> > @@ -682,6 +682,8 @@ int run_syscall(int min, int max)
> > int ret = 0;
> > void *p1, *p2;
> > int has_gettid = 1;
> > + const char *tmpfile = get_tmpfile("/tmp/dummy");
> > + int has_tmpfile = tmpfile != NULL;
> >
> > /* <proc> indicates whether or not /proc is mounted */
> > proc = stat("/proc", &stat_buf) == 0;
> > @@ -720,7 +722,7 @@ int run_syscall(int min, int max)
> > CASE_TEST(chown_self); EXPECT_SYSER(proc, chown("/proc/self", 0, 0), -1, EPERM); break;
> > CASE_TEST(chroot_root); EXPECT_SYSZR(euid0, chroot("/")); break;
> > CASE_TEST(chroot_blah); EXPECT_SYSER(1, chroot("/proc/self/blah"), -1, ENOENT); break;
> > - CASE_TEST(chroot_exe); EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
> > + CASE_TEST(chroot_tmpfile); EXPECT_SYSER(has_tmpfile, chroot(tmpfile), -1, ENOTDIR); break;
>
> get_tempfile() looks really weird.

Yes, it is, it has been used in another patch, but now, only has one user, let's remove it.

> Given that the nolibc implementation of chroot() is the most trivial
> imaginable in my opinion we can keep the current "chroot_exe" that is
> using procfs.
>

Just did some new tests, what about this one?

- CASE_TEST(chroot_exe); EXPECT_SYSER(proc, chroot("/proc/self/exe"), -1, ENOTDIR); break;
+ CASE_TEST(chroot_exe); EXPECT_SYSER2(1, chroot(proc ? "/proc/self/exe" : "/init"), -1, ENOENT, ENOTDIR); break;

"/init" added for !procfs, and ENOENT added for !/init ;-)

And for the chmod_tmpfile, it is changed to chmod_tmpdir like this:

CASE_TEST(chmod_tmpdir); mkdir("/tmp/blah", 0755); EXPECT_SYSZR(1, chmod("/tmp/blah", 0555)); rmdir("/tmp/blah"); break;

Not sure if it is possible to use a syscall to return the file path from the fd
without /proc/self/fd/<N>, if so, we could use the open(, O_TMPFILE...) method
to get a random tmpfile, just like the mktemp command does, will run strace on
it ;-)

Thanks,
Zhangjin

> > CASE_TEST(close_m1); EXPECT_SYSER(1, close(-1), -1, EBADF); break;
> > CASE_TEST(close_dup); EXPECT_SYSZR(1, close(dup(0))); break;
> > CASE_TEST(dup_0); tmp = dup(0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
> > --
> > 2.25.1
> >

2023-06-30 12:10:43

by Zhangjin Wu

[permalink] [raw]
Subject: Re: [PATCH v2 00/15] allow run with minimal kernel config

Hi, Thomas

> On 2023-06-30 07:22:39+0800, Zhangjin Wu wrote:
> > Willy, Thomas
> >
> > This is v2 to allow run with minimal kernel config, see v1 [1].
> >
> > It mainly applied the suggestions from Thomas. It is based on our
> > previous v5 sysret helper series [2] and Thomas' chmod_net removal
> > patchset [3].
> >
> > Now, a test report on arm/vexpress-a9 without procfs, shmem, tmpfs, net
> > and memfd_create looks like:
> >
> > LOG: testing report for arm/vexpress-a9:
> >
> > 14 chmod_net [SKIPPED]
>
> Shouldn't this be gone?
>

Yes, if apply your chmod_net removal patches before this series:

LOG: testing report for arm/vexpress-a9:

14 chmod_self [SKIPPED]
16 chown_self [SKIPPED]
40 link_cross [SKIPPED]
0 -fstackprotector not supported [SKIPPED]

139 test(s) passed, 4 skipped, 0 failed.
See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log

LOG: testing summary:

arch/board | result
------------|------------
arm/vexpress-a9 | 139 test(s) passed, 4 skipped, 0 failed. See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log

This test also applied the new proposed chroot_exe and chmod_tmpfile
from https://lore.kernel.org/lkml/[email protected]/

> > 15 chmod_self [SKIPPED]
> > 17 chown_self [SKIPPED]
> > 41 link_cross [SKIPPED]
> > 0 -fstackprotector not supported [SKIPPED]
> >
> > 139 test(s) passed, 5 skipped, 0 failed.
> > See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log
> >
> > LOG: testing summary:
> >
> > arch/board | result
> > ------------|------------
> > arm/vexpress-a9 | 139 test(s) passed, 5 skipped, 0 failed. See all results in /labs/linux-lab/logging/nolibc/arm-vexpress-a9-nolibc-test.log
>
> > [..]
>
> > tools/include/nolibc/sys.h | 22 ++++
> > tools/testing/selftests/nolibc/nolibc-test.c | 102 +++++++++++++++----
> > 2 files changed, 106 insertions(+), 18 deletions(-)
>
> A few nitpicks left, mentioned on the patches themselves.
>
> In general: for the full series.
>
> Reviewed-by: Thomas Weißschuh <[email protected]>
>

Thanks Thomas, will send v3 later.

Best regards,
Zhangjin