Hi all,
This is a cleanup series to consolidate a common signal setup code. Right now quite a bit of duplicated code is there in an unorganized way. Here is a rework of that signal-related code:
(1) Consolidate the signal handler helpers
They have been exactly copied everywhere. Place them in the shared code. Then, remove those duplicates.
(2) Simplify altstack code
Most cases require just a usable alternate stack. So, there is a chance to simplify them all. Abstract the entire setup code to one setup call. Then, it can reduce the amount of code there.
For testing sigaltstack() specifically, another helper is provided that excludes the syscall part.
The series also includes some preparatory changes for them:
* Along with the rework, some existing problem was uncovered. A couple of tests look to free the altstack memory even before the signal delivery. Adjust the memory cleanup to resolve this issue.
* Also resolve a define conflict separately before including the refactored header.
Then, there is another selftest fix that I posted: https://lore.kernel.org/lkml/20230330233520.21937-1-chang.seok.bae@intel.com... which has a conflict with this. As the fix should go first, this cleanup series is based on it.
FWIW, at the moment, the new x86 selftest cases -- lam and test_shadow_stack do not conflict with this.
Here is the repository where this series can be found: git://github.com/intel/amx-linux.git selftest-signal
Thanks, Chang
Chang S. Bae (4): selftests/x86: Fix the altstack free selftests/x86/mov_ss_trap: Include processor-flags.h selftests/x86: Consolidate signal handler helpers selftests/x86: Refactor altstack setup code
tools/testing/selftests/x86/Makefile | 16 ++- tools/testing/selftests/x86/amx.c | 67 +++-------- .../selftests/x86/corrupt_xstate_header.c | 15 +-- tools/testing/selftests/x86/entry_from_vm86.c | 25 +--- tools/testing/selftests/x86/fsgsbase.c | 25 +--- tools/testing/selftests/x86/helpers.c | 110 ++++++++++++++++++ tools/testing/selftests/x86/helpers.h | 10 ++ tools/testing/selftests/x86/ioperm.c | 26 +---- tools/testing/selftests/x86/iopl.c | 26 +---- tools/testing/selftests/x86/ldt_gdt.c | 19 +-- tools/testing/selftests/x86/mov_ss_trap.c | 26 +---- tools/testing/selftests/x86/ptrace_syscall.c | 24 +--- tools/testing/selftests/x86/sigaltstack.c | 67 +++-------- tools/testing/selftests/x86/sigreturn.c | 35 +----- .../selftests/x86/single_step_syscall.c | 36 +----- .../testing/selftests/x86/syscall_arg_fault.c | 24 +--- tools/testing/selftests/x86/syscall_nt.c | 13 --- tools/testing/selftests/x86/sysret_rip.c | 24 +--- tools/testing/selftests/x86/test_vsyscall.c | 13 --- tools/testing/selftests/x86/unwind_vdso.c | 13 --- 20 files changed, 205 insertions(+), 409 deletions(-) create mode 100644 tools/testing/selftests/x86/helpers.c
Some altstacks are freed up too early even before the test signal delivery. Move the memory cleanup after a signal return.
Fixes: a051b2e56f2a ("selftests/x86: Fix error: variably modified 'altstack_data' at file scope") Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: Shuah Khan shuah@kernel.org Cc: Jun Miao jun.miao@windriver.com Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- The issue was discovered by the altstack refactoring in this series that replaces malloc()/free() with mmap()/munmap(). --- tools/testing/selftests/x86/mov_ss_trap.c | 17 ++++++++++------- .../testing/selftests/x86/single_step_syscall.c | 17 ++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index cc3de6ff9fba..6b9bf8dc3b60 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -142,8 +142,17 @@ static void handle_and_longjmp(int sig, siginfo_t *si, void *ctx_void)
int main() { + stack_t stack = { }; unsigned long nr;
+ stack.ss_size = SIGSTKSZ; + stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); + if (!stack.ss_sp) + err(1, "malloc()"); + + if (sigaltstack(&stack, NULL) != 0) + err(1, "sigaltstack()"); + asm volatile ("mov %%ss, %[ss]" : [ss] "=m" (ss)); printf("\tSS = 0x%hx, &SS = 0x%p\n", ss, &ss);
@@ -248,15 +257,8 @@ int main() */ if (sigsetjmp(jmpbuf, 1) == 0) { printf("[RUN]\tMOV SS; SYSENTER\n"); - stack_t stack = { - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack"); sethandler(SIGSEGV, handle_and_longjmp, SA_RESETHAND | SA_ONSTACK); nr = SYS_getpid; - free(stack.ss_sp); /* Clear EBP first to make sure we segfault cleanly. */ asm volatile ("xorl %%ebp, %%ebp; mov %[ss], %%ss; SYSENTER" : "+a" (nr) : [ss] "m" (ss) : "flags", "rcx" @@ -281,6 +283,7 @@ int main() ); }
+ free(stack.ss_sp); printf("[OK]\tI aten't dead\n"); return 0; } diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 9a30f443e928..2d8e0edca23f 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -144,10 +144,19 @@ static void fast_syscall_no_tf(void)
int main() { + stack_t stack = { }; #ifdef CAN_BUILD_32 int tmp; #endif
+ stack.ss_size = SIGSTKSZ; + stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); + if (!stack.ss_sp) + err(1, "malloc()"); + + if (sigaltstack(&stack, NULL) != 0) + err(1, "sigaltstack()"); + sethandler(SIGTRAP, sigtrap, 0);
printf("[RUN]\tSet TF and check nop\n"); @@ -208,17 +217,10 @@ int main() if (sigsetjmp(jmpbuf, 1) == 0) { unsigned long nr = SYS_getpid; printf("[RUN]\tSet TF and check SYSENTER\n"); - stack_t stack = { - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack"); sethandler(SIGSEGV, print_and_longjmp, SA_RESETHAND | SA_ONSTACK); sethandler(SIGILL, print_and_longjmp, SA_RESETHAND); set_eflags(get_eflags() | X86_EFLAGS_TF); - free(stack.ss_sp); /* Clear EBP first to make sure we segfault cleanly. */ asm volatile ("xorl %%ebp, %%ebp; SYSENTER" : "+a" (nr) :: "flags", "rcx" #ifdef __x86_64__ @@ -238,5 +240,6 @@ int main() /* Now make sure that another fast syscall doesn't set TF again. */ fast_syscall_no_tf();
+ free(stack.ss_sp); return 0; }
Instead of defining X86_EFLAGS_RF, include the header file.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: Shuah Khan shuah@kernel.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- Resolve here before including helper.h in the next patch which, otherwise, has to remove the define there along with other changes. --- tools/testing/selftests/x86/mov_ss_trap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index 6b9bf8dc3b60..f8633aafc90c 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -35,8 +35,7 @@ #include <string.h> #include <setjmp.h> #include <sys/prctl.h> - -#define X86_EFLAGS_RF (1UL << 16) +#include <asm/processor-flags.h>
#if __x86_64__ # define REG_IP REG_RIP
Many test cases have the same signal handler (un)register helpers which have been copied exactly over there.
Clean up this by moving this helper into a common place. Also, update the Makefile to support this shared code.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: Shuah Khan shuah@kernel.org Cc: Andy Lutomirski luto@kernel.org Cc: Thomas Gleixner tglx@linutronix.de Cc: Borislav Petkov bp@alien8.de Cc: linux-kernel@vger.kernel.org Cc: linux-kselftest@vger.kernel.org --- tools/testing/selftests/x86/Makefile | 16 ++++++++-- tools/testing/selftests/x86/amx.c | 25 +--------------- .../selftests/x86/corrupt_xstate_header.c | 15 +--------- tools/testing/selftests/x86/entry_from_vm86.c | 25 ++-------------- tools/testing/selftests/x86/fsgsbase.c | 25 ++-------------- tools/testing/selftests/x86/helpers.c | 30 +++++++++++++++++++ tools/testing/selftests/x86/helpers.h | 6 ++++ tools/testing/selftests/x86/ioperm.c | 26 ++-------------- tools/testing/selftests/x86/iopl.c | 26 ++-------------- tools/testing/selftests/x86/ldt_gdt.c | 19 +++--------- tools/testing/selftests/x86/mov_ss_trap.c | 15 ++-------- tools/testing/selftests/x86/ptrace_syscall.c | 24 ++------------- tools/testing/selftests/x86/sigaltstack.c | 27 ++--------------- tools/testing/selftests/x86/sigreturn.c | 25 ++-------------- .../selftests/x86/single_step_syscall.c | 23 -------------- .../testing/selftests/x86/syscall_arg_fault.c | 13 -------- tools/testing/selftests/x86/syscall_nt.c | 13 -------- tools/testing/selftests/x86/sysret_rip.c | 24 +-------------- tools/testing/selftests/x86/test_vsyscall.c | 13 -------- tools/testing/selftests/x86/unwind_vdso.c | 13 -------- 20 files changed, 72 insertions(+), 331 deletions(-) create mode 100644 tools/testing/selftests/x86/helpers.c
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index ca9374b56ead..382585a314c0 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -36,6 +36,10 @@ BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64))
CFLAGS := -O2 -g -std=gnu99 -pthread -Wall $(KHDR_INCLUDES)
+LIB := helpers +LIB_OBJ_32 := $(patsubst %,$(OUTPUT)/%.o,$(LIB:%=%_32)) +LIB_OBJ_64 := $(patsubst %,$(OUTPUT)/%.o,$(LIB:%=%_64)) + # call32_from_64 in thunks.S uses absolute addresses. ifeq ($(CAN_BUILD_WITH_NOPIE),1) CFLAGS += -no-pie @@ -69,12 +73,18 @@ all_32: $(BINARIES_32)
all_64: $(BINARIES_64)
-EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) +EXTRA_CLEAN := $(BINARIES_32) $(BINARIES_64) $(LIB_OBJ_32) $(LIB_OBJ_64) + +$(LIB_OBJ_32): $(OUTPUT)/%_32.o: %.c + $(CC) -O -m32 -o $@ -c $^ $(CFLAGS) $(EXTRA_CFLAGS) + +$(LIB_OBJ_64): $(OUTPUT)/%_64.o: %.c + $(CC) -O -m64 -o $@ -c $^ $(CFLAGS) $(EXTRA_CFLAGS)
-$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h +$(BINARIES_32): $(OUTPUT)/%_32: %.c helpers.h $(LIB_OBJ_32) $(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm
-$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h +$(BINARIES_64): $(OUTPUT)/%_64: %.c helpers.h $(LIB_OBJ_64) $(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
# x86_64 users should be encouraged to install 32-bit libraries diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 854f7d61be89..1e8e60b1f7b9 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -20,6 +20,7 @@ #include <sys/uio.h>
#include "../kselftest.h" /* For __cpuid_count() */ +#include "helpers.h"
#ifndef __x86_64__ # error This test is 64-bit only @@ -61,30 +62,6 @@ static inline void xrstor(struct xsave_buffer *xbuf, uint64_t rfbm) /* err() exits and will not return */ #define fatal_error(msg, ...) err(1, "[FAIL]\t" msg, ##__VA_ARGS__)
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - fatal_error("sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - fatal_error("sigaction"); -} - #define XFEATURE_XTILECFG 17 #define XFEATURE_XTILEDATA 18 #define XFEATURE_MASK_XTILECFG (1 << XFEATURE_XTILECFG) diff --git a/tools/testing/selftests/x86/corrupt_xstate_header.c b/tools/testing/selftests/x86/corrupt_xstate_header.c index cf9ce8fbb656..111ec58cd1d0 100644 --- a/tools/testing/selftests/x86/corrupt_xstate_header.c +++ b/tools/testing/selftests/x86/corrupt_xstate_header.c @@ -11,13 +11,13 @@ #include <stdio.h> #include <string.h> #include <sched.h> -#include <signal.h> #include <err.h> #include <unistd.h> #include <stdint.h> #include <sys/wait.h>
#include "../kselftest.h" /* For __cpuid_count() */ +#include "helpers.h"
static inline int xsave_enabled(void) { @@ -29,19 +29,6 @@ static inline int xsave_enabled(void) return ecx & (1U << 27); }
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void sigusr1(int sig, siginfo_t *info, void *uc_void) { ucontext_t *uc = uc_void; diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c index d1e919b0c1dc..535596f9ce24 100644 --- a/tools/testing/selftests/x86/entry_from_vm86.c +++ b/tools/testing/selftests/x86/entry_from_vm86.c @@ -11,7 +11,6 @@ #include <assert.h> #include <stdlib.h> #include <sys/syscall.h> -#include <sys/signal.h> #include <sys/ucontext.h> #include <unistd.h> #include <stdio.h> @@ -24,31 +23,11 @@ #include <errno.h> #include <sys/vm86.h>
+#include "helpers.h" + static unsigned long load_addr = 0x10000; static int nerrs = 0;
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static sig_atomic_t got_signal;
static void sighandler(int sig, siginfo_t *info, void *ctx_void) diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c index 8c780cce941d..94642c57e483 100644 --- a/tools/testing/selftests/x86/fsgsbase.c +++ b/tools/testing/selftests/x86/fsgsbase.c @@ -15,7 +15,6 @@ #include <sys/user.h> #include <asm/prctl.h> #include <sys/prctl.h> -#include <signal.h> #include <limits.h> #include <sys/ucontext.h> #include <sched.h> @@ -28,6 +27,8 @@ #include <sys/wait.h> #include <setjmp.h>
+#include "helpers.h" + #ifndef __x86_64__ # error This test is 64-bit only #endif @@ -39,28 +40,6 @@ static unsigned short *shared_scratch;
static int nerrs;
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void sigsegv(int sig, siginfo_t *si, void *ctx_void) { ucontext_t *ctx = (ucontext_t*)ctx_void; diff --git a/tools/testing/selftests/x86/helpers.c b/tools/testing/selftests/x86/helpers.c new file mode 100644 index 000000000000..a6ecc42d359f --- /dev/null +++ b/tools/testing/selftests/x86/helpers.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only +#define _GNU_SOURCE +#include <string.h> +#include <err.h> + +#include "helpers.h" + +void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +void clearhandler(int sig) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} diff --git a/tools/testing/selftests/x86/helpers.h b/tools/testing/selftests/x86/helpers.h index 4ef42c4559a9..35ff4df35397 100644 --- a/tools/testing/selftests/x86/helpers.h +++ b/tools/testing/selftests/x86/helpers.h @@ -2,8 +2,14 @@ #ifndef __SELFTESTS_X86_HELPERS_H #define __SELFTESTS_X86_HELPERS_H
+#include <signal.h> #include <asm/processor-flags.h>
+void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags); + +void clearhandler(int sig); + static inline unsigned long get_eflags(void) { #ifdef __x86_64__ diff --git a/tools/testing/selftests/x86/ioperm.c b/tools/testing/selftests/x86/ioperm.c index 57ec5e99edb9..103573c3d855 100644 --- a/tools/testing/selftests/x86/ioperm.c +++ b/tools/testing/selftests/x86/ioperm.c @@ -8,7 +8,6 @@ #include <err.h> #include <stdio.h> #include <stdint.h> -#include <signal.h> #include <setjmp.h> #include <stdlib.h> #include <string.h> @@ -20,30 +19,9 @@ #include <sched.h> #include <sys/io.h>
-static int nerrs = 0; - -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); - -} +#include "helpers.h"
-static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} +static int nerrs = 0;
static jmp_buf jmpbuf;
diff --git a/tools/testing/selftests/x86/iopl.c b/tools/testing/selftests/x86/iopl.c index 7e3e09c1abac..09544e598def 100644 --- a/tools/testing/selftests/x86/iopl.c +++ b/tools/testing/selftests/x86/iopl.c @@ -8,7 +8,6 @@ #include <err.h> #include <stdio.h> #include <stdint.h> -#include <signal.h> #include <setjmp.h> #include <stdlib.h> #include <string.h> @@ -20,30 +19,9 @@ #include <sched.h> #include <sys/io.h>
-static int nerrs = 0; - -static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); - -} +#include "helpers.h"
-static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} +static int nerrs = 0;
static jmp_buf jmpbuf;
diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c index 3a29346e1452..80acade5d7df 100644 --- a/tools/testing/selftests/x86/ldt_gdt.c +++ b/tools/testing/selftests/x86/ldt_gdt.c @@ -8,7 +8,6 @@ #include <err.h> #include <stdio.h> #include <stdint.h> -#include <signal.h> #include <setjmp.h> #include <stdlib.h> #include <string.h> @@ -26,6 +25,8 @@ #include <asm/prctl.h> #include <sys/prctl.h>
+#include "helpers.h" + #define AR_ACCESSED (1<<8)
#define AR_TYPE_RODATA (0 * (1<<9)) @@ -506,20 +507,6 @@ static void fix_sa_restorer(int sig) } #endif
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); - - fix_sa_restorer(sig); -} - static jmp_buf jmpbuf;
static void sigsegv(int sig, siginfo_t *info, void *ctx_void) @@ -549,9 +536,11 @@ static void do_multicpu_tests(void) }
sethandler(SIGSEGV, sigsegv, 0); + fix_sa_restorer(SIGSEGV); #ifdef __i386__ /* True 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */ sethandler(SIGILL, sigsegv, 0); + fix_sa_restorer(SIGILL); #endif
printf("[RUN]\tCross-CPU LDT invalidation\n"); diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index f8633aafc90c..cfec7a3e30b7 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -35,7 +35,8 @@ #include <string.h> #include <setjmp.h> #include <sys/prctl.h> -#include <asm/processor-flags.h> + +#include "helpers.h"
#if __x86_64__ # define REG_IP REG_RIP @@ -93,18 +94,6 @@ static void enable_watchpoint(void) } }
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static char const * const signames[] = { [SIGSEGV] = "SIGSEGV", [SIGBUS] = "SIBGUS", diff --git a/tools/testing/selftests/x86/ptrace_syscall.c b/tools/testing/selftests/x86/ptrace_syscall.c index 12aaa063196e..360ec88d5432 100644 --- a/tools/testing/selftests/x86/ptrace_syscall.c +++ b/tools/testing/selftests/x86/ptrace_syscall.c @@ -15,6 +15,8 @@ #include <asm/ptrace-abi.h> #include <sys/auxv.h>
+#include "helpers.h" + /* Bitness-agnostic defines for user_regs_struct fields. */ #ifdef __x86_64__ # define user_syscall_nr orig_rax @@ -93,18 +95,6 @@ static siginfo_t wait_trap(pid_t chld) return si; }
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void setsigign(int sig, int flags) { struct sigaction sa; @@ -116,16 +106,6 @@ static void setsigign(int sig, int flags) err(1, "sigaction"); }
-static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - #ifdef __x86_64__ # define REG_BP REG_RBP #else diff --git a/tools/testing/selftests/x86/sigaltstack.c b/tools/testing/selftests/x86/sigaltstack.c index 22a88b764a8e..7c2bd27908d5 100644 --- a/tools/testing/selftests/x86/sigaltstack.c +++ b/tools/testing/selftests/x86/sigaltstack.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only
#define _GNU_SOURCE -#include <signal.h> #include <stdio.h> #include <stdbool.h> #include <string.h> @@ -14,6 +13,8 @@ #include <sys/resource.h> #include <setjmp.h>
+#include "helpers.h" + /* sigaltstack()-enforced minimum stack */ #define ENFORCED_MINSIGSTKSZ 2048
@@ -27,30 +28,6 @@ static bool sigalrm_expected;
static unsigned long at_minstack_size;
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static int setup_altstack(void *start, unsigned long size) { stack_t ss; diff --git a/tools/testing/selftests/x86/sigreturn.c b/tools/testing/selftests/x86/sigreturn.c index 5d7961a5f7f6..b2282ca57e23 100644 --- a/tools/testing/selftests/x86/sigreturn.c +++ b/tools/testing/selftests/x86/sigreturn.c @@ -36,7 +36,6 @@ #include <string.h> #include <inttypes.h> #include <sys/mman.h> -#include <sys/signal.h> #include <sys/ucontext.h> #include <asm/ldt.h> #include <err.h> @@ -46,6 +45,8 @@ #include <sys/ptrace.h> #include <sys/user.h>
+#include "helpers.h" + /* Pull in AR_xyz defines. */ typedef unsigned int u32; typedef unsigned short u16; @@ -138,28 +139,6 @@ static unsigned short LDT3(int idx) return (idx << 3) | 7; }
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void add_ldt(const struct user_desc *desc, unsigned short *var, const char *name) { diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 2d8e0edca23f..4c9b8fd7a41a 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -21,7 +21,6 @@ #include <string.h> #include <inttypes.h> #include <sys/mman.h> -#include <sys/signal.h> #include <sys/ucontext.h> #include <asm/ldt.h> #include <err.h> @@ -33,28 +32,6 @@
#include "helpers.h"
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static volatile sig_atomic_t sig_traps, sig_eflags; sigjmp_buf jmpbuf;
diff --git a/tools/testing/selftests/x86/syscall_arg_fault.c b/tools/testing/selftests/x86/syscall_arg_fault.c index 461fa41a4d02..1149ac24921a 100644 --- a/tools/testing/selftests/x86/syscall_arg_fault.c +++ b/tools/testing/selftests/x86/syscall_arg_fault.c @@ -9,7 +9,6 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <sys/signal.h> #include <sys/ucontext.h> #include <err.h> #include <setjmp.h> @@ -17,18 +16,6 @@
#include "helpers.h"
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static volatile sig_atomic_t sig_traps; static sigjmp_buf jmpbuf;
diff --git a/tools/testing/selftests/x86/syscall_nt.c b/tools/testing/selftests/x86/syscall_nt.c index a108b80dd082..1a019bc43b9d 100644 --- a/tools/testing/selftests/x86/syscall_nt.c +++ b/tools/testing/selftests/x86/syscall_nt.c @@ -10,7 +10,6 @@ #include <stdio.h> #include <unistd.h> #include <string.h> -#include <signal.h> #include <err.h> #include <sys/syscall.h>
@@ -18,18 +17,6 @@
static unsigned int nerrs;
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static void sigtrap(int sig, siginfo_t *si, void *ctx_void) { } diff --git a/tools/testing/selftests/x86/sysret_rip.c b/tools/testing/selftests/x86/sysret_rip.c index 84d74be1d902..da5164fde79a 100644 --- a/tools/testing/selftests/x86/sysret_rip.c +++ b/tools/testing/selftests/x86/sysret_rip.c @@ -11,7 +11,6 @@ #include <stdio.h> #include <string.h> #include <inttypes.h> -#include <sys/signal.h> #include <sys/ucontext.h> #include <sys/syscall.h> #include <err.h> @@ -22,6 +21,7 @@ #include <sys/mman.h> #include <assert.h>
+#include "helpers.h"
asm ( ".pushsection ".text", "ax"\n\t" @@ -39,28 +39,6 @@ asm ( extern const char test_page[]; static void const *current_test_page_addr = test_page;
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - -static void clearhandler(int sig) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = SIG_DFL; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - /* State used by our signal handlers. */ static gregset_t initial_regs;
diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index 47cab972807c..d54f5e767abe 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c @@ -11,7 +11,6 @@ #include <dlfcn.h> #include <string.h> #include <inttypes.h> -#include <signal.h> #include <sys/ucontext.h> #include <errno.h> #include <err.h> @@ -39,18 +38,6 @@ /* max length of lines in /proc/self/maps - anything longer is skipped here */ #define MAPS_LINE_LEN 128
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - /* vsyscalls and vDSO */ bool vsyscall_map_r = false, vsyscall_map_x = false;
diff --git a/tools/testing/selftests/x86/unwind_vdso.c b/tools/testing/selftests/x86/unwind_vdso.c index 4c311e1af4c7..51ba53904130 100644 --- a/tools/testing/selftests/x86/unwind_vdso.c +++ b/tools/testing/selftests/x86/unwind_vdso.c @@ -31,7 +31,6 @@ int main() #include <string.h> #include <inttypes.h> #include <sys/mman.h> -#include <signal.h> #include <sys/ucontext.h> #include <err.h> #include <stddef.h> @@ -43,18 +42,6 @@ int main() #include <dlfcn.h> #include <unwind.h>
-static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), - int flags) -{ - struct sigaction sa; - memset(&sa, 0, sizeof(sa)); - sa.sa_sigaction = handler; - sa.sa_flags = SA_SIGINFO | flags; - sigemptyset(&sa.sa_mask); - if (sigaction(sig, &sa, 0)) - err(1, "sigaction"); -} - static volatile sig_atomic_t nerrs; static unsigned long sysinfo; static bool got_sysinfo = false;
The sigaltstack setup code is almost the same across x86 tests. Most of the test probably just needs a ready-to-use altstack instead of all the setup code.
Refactor them to these helpers to simplify the test code:
- setup_sigaltstack()
Allocate an altstack memory with a size more than the kernel-provided minimum. Then register the altstack via sigaltstack(2).
- cleanup_sigaltstack()
Unregister the altstack and free up the memory.
Then, these two function calls are supposed to be enough for most sigaltstack-needed test cases. But, when explicit sigaltstack() is needed, another helper is available:
- init_sigaltstack()
Do the same as setup_sigaltstack(), except for not invoking the sigaltstack syscall.
Finally, while here, ensure an altstack cleanup everywhere an altstack is used.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Cc: Shuah Khan shuah@kernel.org Cc: Borislav Petkov bp@alien8.de Cc: Thomas Gleixner tglx@linutronix.de Cc: Andy Lutomirski luto@kernel.org Cc: linux-kselftest@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- The patch is based on another series that fixes the sigaltstack test: https://lore.kernel.org/all/20230330233520.21937-2-chang.seok.bae@intel.com/
Considerably that fix should go first before this cleanup rework. --- tools/testing/selftests/x86/amx.c | 42 ++++------ tools/testing/selftests/x86/helpers.c | 80 +++++++++++++++++++ tools/testing/selftests/x86/helpers.h | 4 + tools/testing/selftests/x86/mov_ss_trap.c | 11 +-- tools/testing/selftests/x86/sigaltstack.c | 40 ++++------ tools/testing/selftests/x86/sigreturn.c | 10 +-- .../selftests/x86/single_step_syscall.c | 12 +-- .../testing/selftests/x86/syscall_arg_fault.c | 11 +-- 8 files changed, 130 insertions(+), 80 deletions(-)
diff --git a/tools/testing/selftests/x86/amx.c b/tools/testing/selftests/x86/amx.c index 1e8e60b1f7b9..70e1d64e9c57 100644 --- a/tools/testing/selftests/x86/amx.c +++ b/tools/testing/selftests/x86/amx.c @@ -362,29 +362,11 @@ static void validate_xcomp_perm(enum expected_result exp) # define AT_MINSIGSTKSZ 51 #endif
-static void *alloc_altstack(unsigned int size) +static void setup_altstack(stack_t *stack, enum expected_result exp) { - void *altstack; - - altstack = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - - if (altstack == MAP_FAILED) - fatal_error("mmap() for altstack"); - - return altstack; -} - -static void setup_altstack(void *addr, unsigned long size, enum expected_result exp) -{ - stack_t ss; int rc;
- memset(&ss, 0, sizeof(ss)); - ss.ss_size = size; - ss.ss_sp = addr; - - rc = sigaltstack(&ss, NULL); + rc = sigaltstack(stack, NULL);
if (exp == FAIL_EXPECTED) { if (rc) { @@ -401,7 +383,7 @@ static void test_dynamic_sigaltstack(void) { unsigned int small_size, enough_size; unsigned long minsigstksz; - void *altstack; + stack_t stack = { };
minsigstksz = getauxval(AT_MINSIGSTKSZ); printf("\tAT_MINSIGSTKSZ = %lu\n", minsigstksz); @@ -416,9 +398,9 @@ static void test_dynamic_sigaltstack(void) return; }
- enough_size = minsigstksz * 2; - - altstack = alloc_altstack(enough_size); + if (init_sigaltstack(&stack) != 0) + fatal_error("sigaltstack allocation failed."); + enough_size = stack.ss_size; printf("\tAllocate memory for altstack (%u bytes).\n", enough_size);
/* @@ -427,7 +409,8 @@ static void test_dynamic_sigaltstack(void) */ small_size = minsigstksz - xtiledata.size; printf("\tAfter sigaltstack() with small size (%u bytes).\n", small_size); - setup_altstack(altstack, small_size, SUCCESS_EXPECTED); + stack.ss_size = small_size; + setup_altstack(&stack, SUCCESS_EXPECTED); validate_req_xcomp_perm(FAIL_EXPECTED);
/* @@ -436,7 +419,8 @@ static void test_dynamic_sigaltstack(void) * and thus ARCH_REQ_XCOMP_PERM should succeed. */ printf("\tAfter sigaltstack() with enough size (%u bytes).\n", enough_size); - setup_altstack(altstack, enough_size, SUCCESS_EXPECTED); + stack.ss_size = enough_size; + setup_altstack(&stack, SUCCESS_EXPECTED); validate_req_xcomp_perm(SUCCESS_EXPECTED);
/* @@ -446,7 +430,11 @@ static void test_dynamic_sigaltstack(void) * once XTILEDATA permission is established. */ printf("\tThen, sigaltstack() with small size (%u bytes).\n", small_size); - setup_altstack(altstack, small_size, FAIL_EXPECTED); + stack.ss_size = small_size; + setup_altstack(&stack, FAIL_EXPECTED); + + stack.ss_size = enough_size; + cleanup_sigaltstack(&stack); }
static void test_dynamic_state(void) diff --git a/tools/testing/selftests/x86/helpers.c b/tools/testing/selftests/x86/helpers.c index a6ecc42d359f..1f5b1e5a3d66 100644 --- a/tools/testing/selftests/x86/helpers.c +++ b/tools/testing/selftests/x86/helpers.c @@ -3,6 +3,15 @@ #include <string.h> #include <err.h>
+#include <sys/auxv.h> +#include <sys/mman.h> + +#include "helpers.h" + +#ifndef AT_MINSIGSTKSZ +# define AT_MINSIGSTKSZ 51 +#endif + #include "helpers.h"
void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), @@ -28,3 +37,74 @@ void clearhandler(int sig) if (sigaction(sig, &sa, 0)) err(1, "sigaction"); } + +#define ALTSTKSZ 8096 + +static unsigned long get_sigaltstacksz(void) +{ + return getauxval(AT_MINSIGSTKSZ) + ALTSTKSZ; +} + +/** + * init_sigalstack -- allocate an altstack without registration + * @stack: stack_t pointer + * Returns: 0 if successful; otherwise, nonzero + * + * Unless testing with different sizes, setup_sigaltstack() should be + * enough to provide a ready-to-use stack + */ +int init_sigaltstack(stack_t *stack) +{ + if (!stack) + return -1; + + if (stack->ss_size > 0 && stack->ss_sp > 0) + return 0; + + stack->ss_size = get_sigaltstacksz(); + + stack->ss_sp = mmap(NULL, stack->ss_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); + if (stack->ss_sp == MAP_FAILED) + return -1; + + return 0; +} + +/** + * setup_sigaltstack -- allocate and register an altstack + * @stack: stack_t pointer + * Returns: 0 if successful; otherwise, nonzero + */ +int setup_sigaltstack(stack_t *stack) +{ + int rc; + + rc = init_sigaltstack(stack); + if (rc) + return -1; + + return sigaltstack(stack, NULL); +} + +/** + * cleanup_sigaltstack -- unregister and free an altstack + * @stack: stack_t pointer + * Returns: None + */ +void cleanup_sigaltstack(stack_t *stack) +{ + size_t size; + void *sp; + + if (!stack) + return; + + size = stack->ss_size; + sp = stack->ss_sp; + + stack->ss_flags = SS_DISABLE; + sigaltstack(stack, NULL); + + munmap(sp, size); +} diff --git a/tools/testing/selftests/x86/helpers.h b/tools/testing/selftests/x86/helpers.h index 35ff4df35397..a47ba1a2d929 100644 --- a/tools/testing/selftests/x86/helpers.h +++ b/tools/testing/selftests/x86/helpers.h @@ -5,6 +5,10 @@ #include <signal.h> #include <asm/processor-flags.h>
+int init_sigaltstack(stack_t *stack); +int setup_sigaltstack(stack_t *stack); +void cleanup_sigaltstack(stack_t *stack); + void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), int flags);
diff --git a/tools/testing/selftests/x86/mov_ss_trap.c b/tools/testing/selftests/x86/mov_ss_trap.c index cfec7a3e30b7..c9ffc8b3a214 100644 --- a/tools/testing/selftests/x86/mov_ss_trap.c +++ b/tools/testing/selftests/x86/mov_ss_trap.c @@ -133,13 +133,8 @@ int main() stack_t stack = { }; unsigned long nr;
- stack.ss_size = SIGSTKSZ; - stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); - if (!stack.ss_sp) - err(1, "malloc()"); - - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack()"); + if (setup_sigaltstack(&stack) != 0) + err(1, "sigaltstack");
asm volatile ("mov %%ss, %[ss]" : [ss] "=m" (ss)); printf("\tSS = 0x%hx, &SS = 0x%p\n", ss, &ss); @@ -271,7 +266,7 @@ int main() ); }
- free(stack.ss_sp); + cleanup_sigaltstack(&stack); printf("[OK]\tI aten't dead\n"); return 0; } diff --git a/tools/testing/selftests/x86/sigaltstack.c b/tools/testing/selftests/x86/sigaltstack.c index 7c2bd27908d5..6f753406ca91 100644 --- a/tools/testing/selftests/x86/sigaltstack.c +++ b/tools/testing/selftests/x86/sigaltstack.c @@ -28,17 +28,6 @@ static bool sigalrm_expected;
static unsigned long at_minstack_size;
-static int setup_altstack(void *start, unsigned long size) -{ - stack_t ss; - - memset(&ss, 0, sizeof(ss)); - ss.ss_size = size; - ss.ss_sp = start; - - return sigaltstack(&ss, NULL); -} - static jmp_buf jmpbuf;
static void sigsegv(int sig, siginfo_t *info, void *ctx_void) @@ -63,14 +52,14 @@ static void sigalrm(int sig, siginfo_t *info, void *ctx_void) } }
-static void test_sigaltstack(void *altstack, unsigned long size) +static void test_sigaltstack(stack_t *stack) { - if (setup_altstack(altstack, size)) { + if (sigaltstack(stack, NULL)) { /* * The kernel may return ENOMEM when the altstack size * is insufficient. Skip the test in this case. */ - if (errno == ENOMEM && size < at_minstack_size) { + if (errno == ENOMEM && stack->ss_size < at_minstack_size) { printf("[SKIP]\tThe running kernel disallows an insufficient size.\n"); return; } @@ -78,7 +67,7 @@ static void test_sigaltstack(void *altstack, unsigned long size) err(1, "sigaltstack()"); }
- sigalrm_expected = (size > at_minstack_size) ? true : false; + sigalrm_expected = (stack->ss_size > at_minstack_size) ? true : false;
sethandler(SIGSEGV, sigsegv, 0); sethandler(SIGALRM, sigalrm, SA_ONSTACK); @@ -97,19 +86,24 @@ static void test_sigaltstack(void *altstack, unsigned long size)
int main(void) { - void *altstack; + unsigned long enough_size; + stack_t stack = { };
at_minstack_size = getauxval(AT_MINSIGSTKSZ);
- altstack = mmap(NULL, at_minstack_size + SIGSTKSZ, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); - if (altstack == MAP_FAILED) - err(1, "mmap()"); + if (init_sigaltstack(&stack) != 0) + err(1, "sigaltstack allocation failed."); + enough_size = stack.ss_size; + + if ((ENFORCED_MINSIGSTKSZ + 1) < at_minstack_size) { + stack.ss_size = ENFORCED_MINSIGSTKSZ + 1; + test_sigaltstack(&stack); + }
- if ((ENFORCED_MINSIGSTKSZ + 1) < at_minstack_size) - test_sigaltstack(altstack, ENFORCED_MINSIGSTKSZ + 1); + stack.ss_size = enough_size; + test_sigaltstack(&stack);
- test_sigaltstack(altstack, at_minstack_size + SIGSTKSZ); + cleanup_sigaltstack(&stack);
return nerrs == 0 ? 0 : 1; } diff --git a/tools/testing/selftests/x86/sigreturn.c b/tools/testing/selftests/x86/sigreturn.c index b2282ca57e23..f9e06a13ad82 100644 --- a/tools/testing/selftests/x86/sigreturn.c +++ b/tools/testing/selftests/x86/sigreturn.c @@ -741,17 +741,13 @@ int main() { int total_nerrs = 0; unsigned short my_cs, my_ss; + stack_t stack = { };
asm volatile ("mov %%cs,%0" : "=r" (my_cs)); asm volatile ("mov %%ss,%0" : "=r" (my_ss)); setup_ldt();
- stack_t stack = { - /* Our sigaltstack scratch space. */ - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) + if (setup_sigaltstack(&stack) != 0) err(1, "sigaltstack");
sethandler(SIGUSR1, sigusr1, 0); @@ -849,6 +845,6 @@ int main() total_nerrs += test_nonstrict_ss(); #endif
- free(stack.ss_sp); + cleanup_sigaltstack(&stack); return total_nerrs ? 1 : 0; } diff --git a/tools/testing/selftests/x86/single_step_syscall.c b/tools/testing/selftests/x86/single_step_syscall.c index 4c9b8fd7a41a..4e3224e52e30 100644 --- a/tools/testing/selftests/x86/single_step_syscall.c +++ b/tools/testing/selftests/x86/single_step_syscall.c @@ -126,13 +126,8 @@ int main() int tmp; #endif
- stack.ss_size = SIGSTKSZ; - stack.ss_sp = malloc(sizeof(char) * SIGSTKSZ); - if (!stack.ss_sp) - err(1, "malloc()"); - - if (sigaltstack(&stack, NULL) != 0) - err(1, "sigaltstack()"); + if (setup_sigaltstack(&stack) != 0) + err(1, "sigaltstack");
sethandler(SIGTRAP, sigtrap, 0);
@@ -193,6 +188,7 @@ int main() */ if (sigsetjmp(jmpbuf, 1) == 0) { unsigned long nr = SYS_getpid; + printf("[RUN]\tSet TF and check SYSENTER\n"); sethandler(SIGSEGV, print_and_longjmp, SA_RESETHAND | SA_ONSTACK); @@ -217,6 +213,6 @@ int main() /* Now make sure that another fast syscall doesn't set TF again. */ fast_syscall_no_tf();
- free(stack.ss_sp); + cleanup_sigaltstack(&stack); return 0; } diff --git a/tools/testing/selftests/x86/syscall_arg_fault.c b/tools/testing/selftests/x86/syscall_arg_fault.c index 1149ac24921a..1b22ef548582 100644 --- a/tools/testing/selftests/x86/syscall_arg_fault.c +++ b/tools/testing/selftests/x86/syscall_arg_fault.c @@ -87,12 +87,9 @@ static void sigill(int sig, siginfo_t *info, void *ctx_void)
int main() { - stack_t stack = { - /* Our sigaltstack scratch space. */ - .ss_sp = malloc(sizeof(char) * SIGSTKSZ), - .ss_size = SIGSTKSZ, - }; - if (sigaltstack(&stack, NULL) != 0) + stack_t stack = { }; + + if (setup_sigaltstack(&stack) != 0) err(1, "sigaltstack");
sethandler(SIGSEGV, sigsegv_or_sigbus, SA_ONSTACK); @@ -218,6 +215,6 @@ int main() set_eflags(get_eflags() & ~X86_EFLAGS_TF); #endif
- free(stack.ss_sp); + cleanup_sigaltstack(&stack); return 0; }
linux-kselftest-mirror@lists.linaro.org