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@xxxxxxxxx> Cc: Shuah Khan <shuah@xxxxxxxxxx> Cc: Jun Miao <jun.miao@xxxxxxxxxxxxx> Cc: linux-kselftest@xxxxxxxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx --- 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; } -- 2.17.1