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

Zhangjin Wu falcon at tinylab.org
Tue May 30 04:08:43 PDT 2023


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 at tinylab.org>
---
 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




More information about the linux-riscv mailing list