From 11f0c8e0468a8bc625164f68dd5ff2a9436658db Mon Sep 17 00:00:00 2001 From: Dev Jain Date: Wed, 9 Oct 2024 10:44:23 +0530 Subject: selftests: Rename sigaltstack to generic signal Rename sigaltstack to generic signal directory, to allow adding more signal tests in the future. Signed-off-by: Dev Jain Reviewed-by: Mark Brown Acked-by: Shuah Khan Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 2 +- tools/testing/selftests/sigaltstack/.gitignore | 2 - tools/testing/selftests/sigaltstack/Makefile | 6 - .../selftests/sigaltstack/current_stack_pointer.h | 23 --- tools/testing/selftests/sigaltstack/sas.c | 197 --------------------- tools/testing/selftests/signal/.gitignore | 2 + tools/testing/selftests/signal/Makefile | 6 + .../selftests/signal/current_stack_pointer.h | 23 +++ tools/testing/selftests/signal/sas.c | 197 +++++++++++++++++++++ 9 files changed, 229 insertions(+), 229 deletions(-) delete mode 100644 tools/testing/selftests/sigaltstack/.gitignore delete mode 100644 tools/testing/selftests/sigaltstack/Makefile delete mode 100644 tools/testing/selftests/sigaltstack/current_stack_pointer.h delete mode 100644 tools/testing/selftests/sigaltstack/sas.c create mode 100644 tools/testing/selftests/signal/.gitignore create mode 100644 tools/testing/selftests/signal/Makefile create mode 100644 tools/testing/selftests/signal/current_stack_pointer.h create mode 100644 tools/testing/selftests/signal/sas.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index b38199965f99..3cfad04d0b5c 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -90,7 +90,7 @@ TARGETS += rtc TARGETS += rust TARGETS += seccomp TARGETS += sgx -TARGETS += sigaltstack +TARGETS += signal TARGETS += size TARGETS += sparc64 TARGETS += splice diff --git a/tools/testing/selftests/sigaltstack/.gitignore b/tools/testing/selftests/sigaltstack/.gitignore deleted file mode 100644 index 50a19a8888ce..000000000000 --- a/tools/testing/selftests/sigaltstack/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -sas diff --git a/tools/testing/selftests/sigaltstack/Makefile b/tools/testing/selftests/sigaltstack/Makefile deleted file mode 100644 index 3e96d5d47036..000000000000 --- a/tools/testing/selftests/sigaltstack/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -CFLAGS = -Wall -TEST_GEN_PROGS = sas - -include ../lib.mk - diff --git a/tools/testing/selftests/sigaltstack/current_stack_pointer.h b/tools/testing/selftests/sigaltstack/current_stack_pointer.h deleted file mode 100644 index 09da8f1011ce..000000000000 --- a/tools/testing/selftests/sigaltstack/current_stack_pointer.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -#if __alpha__ -register unsigned long sp asm("$30"); -#elif __arm__ || __aarch64__ || __csky__ || __m68k__ || __mips__ || __riscv -register unsigned long sp asm("sp"); -#elif __i386__ -register unsigned long sp asm("esp"); -#elif __loongarch64 -register unsigned long sp asm("$sp"); -#elif __powerpc__ -register unsigned long sp asm("r1"); -#elif __s390x__ -register unsigned long sp asm("%15"); -#elif __sh__ -register unsigned long sp asm("r15"); -#elif __x86_64__ -register unsigned long sp asm("rsp"); -#elif __XTENSA__ -register unsigned long sp asm("a1"); -#else -#error "implement current_stack_pointer equivalent" -#endif diff --git a/tools/testing/selftests/sigaltstack/sas.c b/tools/testing/selftests/sigaltstack/sas.c deleted file mode 100644 index 07227fab1cc9..000000000000 --- a/tools/testing/selftests/sigaltstack/sas.c +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Stas Sergeev - * - * test sigaltstack(SS_ONSTACK | SS_AUTODISARM) - * If that succeeds, then swapcontext() can be used inside sighandler safely. - * - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../kselftest.h" -#include "current_stack_pointer.h" - -#ifndef SS_AUTODISARM -#define SS_AUTODISARM (1U << 31) -#endif - -#ifndef AT_MINSIGSTKSZ -#define AT_MINSIGSTKSZ 51 -#endif - -static unsigned int stack_size; -static void *sstack, *ustack; -static ucontext_t uc, sc; -static const char *msg = "[OK]\tStack preserved"; -static const char *msg2 = "[FAIL]\tStack corrupted"; -struct stk_data { - char msg[128]; - int flag; -}; - -void my_usr1(int sig, siginfo_t *si, void *u) -{ - char *aa; - int err; - stack_t stk; - struct stk_data *p; - - if (sp < (unsigned long)sstack || - sp >= (unsigned long)sstack + stack_size) { - ksft_exit_fail_msg("SP is not on sigaltstack\n"); - } - /* put some data on stack. other sighandler will try to overwrite it */ - aa = alloca(1024); - assert(aa); - p = (struct stk_data *)(aa + 512); - strcpy(p->msg, msg); - p->flag = 1; - ksft_print_msg("[RUN]\tsignal USR1\n"); - err = sigaltstack(NULL, &stk); - if (err) { - ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - if (stk.ss_flags != SS_DISABLE) - ksft_test_result_fail("tss_flags=%x, should be SS_DISABLE\n", - stk.ss_flags); - else - ksft_test_result_pass( - "sigaltstack is disabled in sighandler\n"); - swapcontext(&sc, &uc); - ksft_print_msg("%s\n", p->msg); - if (!p->flag) { - ksft_exit_fail_msg("[RUN]\tAborting\n"); - exit(EXIT_FAILURE); - } -} - -void my_usr2(int sig, siginfo_t *si, void *u) -{ - char *aa; - struct stk_data *p; - - ksft_print_msg("[RUN]\tsignal USR2\n"); - aa = alloca(1024); - /* dont run valgrind on this */ - /* try to find the data stored by previous sighandler */ - p = memmem(aa, 1024, msg, strlen(msg)); - if (p) { - ksft_test_result_fail("sigaltstack re-used\n"); - /* corrupt the data */ - strcpy(p->msg, msg2); - /* tell other sighandler that his data is corrupted */ - p->flag = 0; - } -} - -static void switch_fn(void) -{ - ksft_print_msg("[RUN]\tswitched to user ctx\n"); - raise(SIGUSR2); - setcontext(&sc); -} - -int main(void) -{ - struct sigaction act; - stack_t stk; - int err; - - /* Make sure more than the required minimum. */ - stack_size = getauxval(AT_MINSIGSTKSZ) + SIGSTKSZ; - ksft_print_msg("[NOTE]\tthe stack size is %u\n", stack_size); - - ksft_print_header(); - ksft_set_plan(3); - - sigemptyset(&act.sa_mask); - act.sa_flags = SA_ONSTACK | SA_SIGINFO; - act.sa_sigaction = my_usr1; - sigaction(SIGUSR1, &act, NULL); - act.sa_sigaction = my_usr2; - sigaction(SIGUSR2, &act, NULL); - sstack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - if (sstack == MAP_FAILED) { - ksft_exit_fail_msg("mmap() - %s\n", strerror(errno)); - return EXIT_FAILURE; - } - - err = sigaltstack(NULL, &stk); - if (err) { - ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - if (stk.ss_flags == SS_DISABLE) { - ksft_test_result_pass( - "Initial sigaltstack state was SS_DISABLE\n"); - } else { - ksft_exit_fail_msg("Initial sigaltstack state was %x; " - "should have been SS_DISABLE\n", stk.ss_flags); - return EXIT_FAILURE; - } - - stk.ss_sp = sstack; - stk.ss_size = stack_size; - stk.ss_flags = SS_ONSTACK | SS_AUTODISARM; - err = sigaltstack(&stk, NULL); - if (err) { - if (errno == EINVAL) { - ksft_test_result_skip( - "[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n"); - /* - * If test cases for the !SS_AUTODISARM variant were - * added, we could still run them. We don't have any - * test cases like that yet, so just exit and report - * success. - */ - return 0; - } else { - ksft_exit_fail_msg( - "sigaltstack(SS_ONSTACK | SS_AUTODISARM) %s\n", - strerror(errno)); - return EXIT_FAILURE; - } - } - - ustack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - if (ustack == MAP_FAILED) { - ksft_exit_fail_msg("mmap() - %s\n", strerror(errno)); - return EXIT_FAILURE; - } - getcontext(&uc); - uc.uc_link = NULL; - uc.uc_stack.ss_sp = ustack; - uc.uc_stack.ss_size = stack_size; - makecontext(&uc, switch_fn, 0); - raise(SIGUSR1); - - err = sigaltstack(NULL, &stk); - if (err) { - ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno)); - exit(EXIT_FAILURE); - } - if (stk.ss_flags != SS_AUTODISARM) { - ksft_exit_fail_msg("ss_flags=%x, should be SS_AUTODISARM\n", - stk.ss_flags); - exit(EXIT_FAILURE); - } - ksft_test_result_pass( - "sigaltstack is still SS_AUTODISARM after signal\n"); - - ksft_exit_pass(); - return 0; -} diff --git a/tools/testing/selftests/signal/.gitignore b/tools/testing/selftests/signal/.gitignore new file mode 100644 index 000000000000..50a19a8888ce --- /dev/null +++ b/tools/testing/selftests/signal/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +sas diff --git a/tools/testing/selftests/signal/Makefile b/tools/testing/selftests/signal/Makefile new file mode 100644 index 000000000000..3e96d5d47036 --- /dev/null +++ b/tools/testing/selftests/signal/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +CFLAGS = -Wall +TEST_GEN_PROGS = sas + +include ../lib.mk + diff --git a/tools/testing/selftests/signal/current_stack_pointer.h b/tools/testing/selftests/signal/current_stack_pointer.h new file mode 100644 index 000000000000..09da8f1011ce --- /dev/null +++ b/tools/testing/selftests/signal/current_stack_pointer.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if __alpha__ +register unsigned long sp asm("$30"); +#elif __arm__ || __aarch64__ || __csky__ || __m68k__ || __mips__ || __riscv +register unsigned long sp asm("sp"); +#elif __i386__ +register unsigned long sp asm("esp"); +#elif __loongarch64 +register unsigned long sp asm("$sp"); +#elif __powerpc__ +register unsigned long sp asm("r1"); +#elif __s390x__ +register unsigned long sp asm("%15"); +#elif __sh__ +register unsigned long sp asm("r15"); +#elif __x86_64__ +register unsigned long sp asm("rsp"); +#elif __XTENSA__ +register unsigned long sp asm("a1"); +#else +#error "implement current_stack_pointer equivalent" +#endif diff --git a/tools/testing/selftests/signal/sas.c b/tools/testing/selftests/signal/sas.c new file mode 100644 index 000000000000..07227fab1cc9 --- /dev/null +++ b/tools/testing/selftests/signal/sas.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Stas Sergeev + * + * test sigaltstack(SS_ONSTACK | SS_AUTODISARM) + * If that succeeds, then swapcontext() can be used inside sighandler safely. + * + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../kselftest.h" +#include "current_stack_pointer.h" + +#ifndef SS_AUTODISARM +#define SS_AUTODISARM (1U << 31) +#endif + +#ifndef AT_MINSIGSTKSZ +#define AT_MINSIGSTKSZ 51 +#endif + +static unsigned int stack_size; +static void *sstack, *ustack; +static ucontext_t uc, sc; +static const char *msg = "[OK]\tStack preserved"; +static const char *msg2 = "[FAIL]\tStack corrupted"; +struct stk_data { + char msg[128]; + int flag; +}; + +void my_usr1(int sig, siginfo_t *si, void *u) +{ + char *aa; + int err; + stack_t stk; + struct stk_data *p; + + if (sp < (unsigned long)sstack || + sp >= (unsigned long)sstack + stack_size) { + ksft_exit_fail_msg("SP is not on sigaltstack\n"); + } + /* put some data on stack. other sighandler will try to overwrite it */ + aa = alloca(1024); + assert(aa); + p = (struct stk_data *)(aa + 512); + strcpy(p->msg, msg); + p->flag = 1; + ksft_print_msg("[RUN]\tsignal USR1\n"); + err = sigaltstack(NULL, &stk); + if (err) { + ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + if (stk.ss_flags != SS_DISABLE) + ksft_test_result_fail("tss_flags=%x, should be SS_DISABLE\n", + stk.ss_flags); + else + ksft_test_result_pass( + "sigaltstack is disabled in sighandler\n"); + swapcontext(&sc, &uc); + ksft_print_msg("%s\n", p->msg); + if (!p->flag) { + ksft_exit_fail_msg("[RUN]\tAborting\n"); + exit(EXIT_FAILURE); + } +} + +void my_usr2(int sig, siginfo_t *si, void *u) +{ + char *aa; + struct stk_data *p; + + ksft_print_msg("[RUN]\tsignal USR2\n"); + aa = alloca(1024); + /* dont run valgrind on this */ + /* try to find the data stored by previous sighandler */ + p = memmem(aa, 1024, msg, strlen(msg)); + if (p) { + ksft_test_result_fail("sigaltstack re-used\n"); + /* corrupt the data */ + strcpy(p->msg, msg2); + /* tell other sighandler that his data is corrupted */ + p->flag = 0; + } +} + +static void switch_fn(void) +{ + ksft_print_msg("[RUN]\tswitched to user ctx\n"); + raise(SIGUSR2); + setcontext(&sc); +} + +int main(void) +{ + struct sigaction act; + stack_t stk; + int err; + + /* Make sure more than the required minimum. */ + stack_size = getauxval(AT_MINSIGSTKSZ) + SIGSTKSZ; + ksft_print_msg("[NOTE]\tthe stack size is %u\n", stack_size); + + ksft_print_header(); + ksft_set_plan(3); + + sigemptyset(&act.sa_mask); + act.sa_flags = SA_ONSTACK | SA_SIGINFO; + act.sa_sigaction = my_usr1; + sigaction(SIGUSR1, &act, NULL); + act.sa_sigaction = my_usr2; + sigaction(SIGUSR2, &act, NULL); + sstack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + if (sstack == MAP_FAILED) { + ksft_exit_fail_msg("mmap() - %s\n", strerror(errno)); + return EXIT_FAILURE; + } + + err = sigaltstack(NULL, &stk); + if (err) { + ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + if (stk.ss_flags == SS_DISABLE) { + ksft_test_result_pass( + "Initial sigaltstack state was SS_DISABLE\n"); + } else { + ksft_exit_fail_msg("Initial sigaltstack state was %x; " + "should have been SS_DISABLE\n", stk.ss_flags); + return EXIT_FAILURE; + } + + stk.ss_sp = sstack; + stk.ss_size = stack_size; + stk.ss_flags = SS_ONSTACK | SS_AUTODISARM; + err = sigaltstack(&stk, NULL); + if (err) { + if (errno == EINVAL) { + ksft_test_result_skip( + "[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n"); + /* + * If test cases for the !SS_AUTODISARM variant were + * added, we could still run them. We don't have any + * test cases like that yet, so just exit and report + * success. + */ + return 0; + } else { + ksft_exit_fail_msg( + "sigaltstack(SS_ONSTACK | SS_AUTODISARM) %s\n", + strerror(errno)); + return EXIT_FAILURE; + } + } + + ustack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + if (ustack == MAP_FAILED) { + ksft_exit_fail_msg("mmap() - %s\n", strerror(errno)); + return EXIT_FAILURE; + } + getcontext(&uc); + uc.uc_link = NULL; + uc.uc_stack.ss_sp = ustack; + uc.uc_stack.ss_size = stack_size; + makecontext(&uc, switch_fn, 0); + raise(SIGUSR1); + + err = sigaltstack(NULL, &stk); + if (err) { + ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + if (stk.ss_flags != SS_AUTODISARM) { + ksft_exit_fail_msg("ss_flags=%x, should be SS_AUTODISARM\n", + stk.ss_flags); + exit(EXIT_FAILURE); + } + ksft_test_result_pass( + "sigaltstack is still SS_AUTODISARM after signal\n"); + + ksft_exit_pass(); + return 0; +} -- cgit v1.2.3