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@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;