[PATCH 4/4] selftests/nolibc: add user-space efault restore test case

From: Zhangjin Wu
Date: Tue May 30 2023 - 07:09:02 EST


while the libc supports sigaction/sigsetjmp/siglongjump, it is able to
restore next test after an invalid data pointer access, add such a test
case for these libcs, otherwise, skip it.

With glibc/musl:

29 efault_handler ! 11 SIGSEGV [OK]

With current nolibc:

29 efault_handler [SKIPPED]

Signed-off-by: Zhangjin Wu <falcon@xxxxxxxxxxx>
---
tools/testing/selftests/nolibc/nolibc-test.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 9f9a09529a4f..6b4ebe4be4d6 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -248,6 +248,15 @@ static void register_trap_handler(void)
}
}

+static int test_efault(void)
+{
+ char *addr = (void *)1;
+
+ *addr = 'a';
+
+ return -1;
+}
+
#define has_user_space_efault() (1)
#else
#define record_test_context(idx, iteration, iterations) do { } while (0)
@@ -255,6 +264,7 @@ static void register_trap_handler(void)
#define register_expect_trap(experr1, experr2) do { } while (0)
#define register_trap_handler() do { } while (0)
#define has_user_space_efault() (0)
+#define test_efault(addr) (-1)
#endif

static void putcharn(char c, size_t n)
@@ -690,6 +700,7 @@ int run_syscall(int min, int max)
struct stat stat_buf;
int euid0;
int proc;
+ int efault;
int test;
int tmp;
int ret = 0;
@@ -701,6 +712,9 @@ int run_syscall(int min, int max)
/* this will be used to skip certain tests that can't be run unprivileged */
euid0 = geteuid() == 0;

+ /* user-space efault handler support */
+ efault = has_user_space_efault();
+
for (test = min; test >= 0 && test <= max; test++) {
int llen = 0; /* line length */

@@ -737,6 +751,7 @@ int run_syscall(int min, int max)
CASE_TEST(dup2_m1); tmp = dup2(-1, 100); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
CASE_TEST(dup3_0); tmp = dup3(0, 100, 0); EXPECT_SYSNE(1, tmp, -1); close(tmp); break;
CASE_TEST(dup3_m1); tmp = dup3(-1, 100, 0); EXPECT_SYSER(1, tmp, -1, EBADF); if (tmp != -1) close(tmp); break;
+ CASE_TEST(efault_handler); EXPECT_SYSER(efault, test_efault(), -1, EFAULT); break;
CASE_TEST(execve_root); EXPECT_SYSER(1, execve("/", (char*[]){ [0] = "/", [1] = NULL }, NULL), -1, EACCES); break;
CASE_TEST(fork); EXPECT_SYSZR(1, test_fork()); break;
CASE_TEST(getdents64_root); EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
--
2.25.1