* [PATCH v1 1/1] selftests/x86: Add a test to detect infinite sigtrap handler loop
@ 2025-05-30 23:07 Xin Li (Intel)
2025-05-31 0:14 ` Sohil Mehta
0 siblings, 1 reply; 2+ messages in thread
From: Xin Li (Intel) @ 2025-05-30 23:07 UTC (permalink / raw)
To: linux-kernel, linux-kselftest
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, shuah, andrew.cooper3
When FRED is enabled, if the Trap Flag (TF) is set without an external
debugger attached, it can lead to an infinite loop in the SIGTRAP
handler. To avoid this, the software event flag in the augmented SS
must be cleared, ensuring that no single-step trap remains pending when
ERETU completes.
This test checks for that specific scenario—verifying whether the kernel
correctly prevents an infinite SIGTRAP loop in this edge case.
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
---
tools/testing/selftests/x86/Makefile | 2 +-
.../selftests/x86/test_sigtrap_handler.c | 80 +++++++++++++++++++
2 files changed, 81 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/x86/test_sigtrap_handler.c
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index f703fcfe9f7c..c486fd88ebb1 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -12,7 +12,7 @@ CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh "$(CC)" trivial_program.c -no-pie)
TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
check_initial_reg_state sigreturn iopl ioperm \
- test_vsyscall mov_ss_trap \
+ test_vsyscall mov_ss_trap test_sigtrap_handler \
syscall_arg_fault fsgsbase_restore sigaltstack
TARGETS_C_BOTHBITS += nx_stack
TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
diff --git a/tools/testing/selftests/x86/test_sigtrap_handler.c b/tools/testing/selftests/x86/test_sigtrap_handler.c
new file mode 100644
index 000000000000..9c5c2cf0cf88
--- /dev/null
+++ b/tools/testing/selftests/x86/test_sigtrap_handler.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Intel Corporation
+ */
+#define _GNU_SOURCE
+
+#include <err.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ucontext.h>
+
+#ifdef __x86_64__
+# define REG_IP REG_RIP
+#else
+# define REG_IP REG_EIP
+#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");
+
+ return;
+}
+
+static unsigned int loop_count_on_same_ip;
+
+static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
+{
+ ucontext_t *ctx = (ucontext_t *)ctx_void;
+ static unsigned long last_trap_ip;
+
+ if (last_trap_ip == ctx->uc_mcontext.gregs[REG_IP]) {
+ printf("trapped on %016lx\n", last_trap_ip);
+
+ if (++loop_count_on_same_ip > 10) {
+ printf("trap loop detected, test failed\n");
+ exit(2);
+ }
+
+ return;
+ }
+
+ loop_count_on_same_ip = 0;
+ last_trap_ip = ctx->uc_mcontext.gregs[REG_IP];
+ printf("trapped on %016lx\n", last_trap_ip);
+}
+
+int main(int argc, char *argv[])
+{
+ sethandler(SIGTRAP, sigtrap, 0);
+
+ asm volatile(
+#ifdef __x86_64__
+ /* Avoid clobbering the redzone */
+ "sub $128, %rsp\n\t"
+#endif
+ "push $0x302\n\t"
+ "popf\n\t"
+ "nop\n\t"
+ "nop\n\t"
+ "push $0x202\n\t"
+ "popf\n\t"
+#ifdef __x86_64__
+ "add $128, %rsp\n\t"
+#endif
+ );
+
+ printf("test passed\n");
+ return 0;
+}
base-commit: 485d11d84a2452ac16466cc7ae041c93d38929bc
--
2.49.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH v1 1/1] selftests/x86: Add a test to detect infinite sigtrap handler loop
2025-05-30 23:07 [PATCH v1 1/1] selftests/x86: Add a test to detect infinite sigtrap handler loop Xin Li (Intel)
@ 2025-05-31 0:14 ` Sohil Mehta
0 siblings, 0 replies; 2+ messages in thread
From: Sohil Mehta @ 2025-05-31 0:14 UTC (permalink / raw)
To: Xin Li (Intel)
Cc: tglx, mingo, bp, dave.hansen, x86, hpa, shuah, andrew.cooper3,
linux-kernel, linux-kselftest
On 5/30/2025 4:07 PM, Xin Li (Intel) wrote:
> When FRED is enabled, if the Trap Flag (TF) is set without an external
> debugger attached, it can lead to an infinite loop in the SIGTRAP
> handler. To avoid this, the software event flag in the augmented SS
> must be cleared, ensuring that no single-step trap remains pending when
> ERETU completes.
>
> This test checks for that specific scenario—verifying whether the kernel
> correctly prevents an infinite SIGTRAP loop in this edge case.
>
It isn't clear from the commit message whether the test is specific to
FRED or a generic one.
> Signed-off-by: Xin Li (Intel) <xin@zytor.com>
> ---
> tools/testing/selftests/x86/Makefile | 2 +-
> .../selftests/x86/test_sigtrap_handler.c | 80 +++++++++++++++++++
> 2 files changed, 81 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/x86/test_sigtrap_handler.c
>
> diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
> index f703fcfe9f7c..c486fd88ebb1 100644
> --- a/tools/testing/selftests/x86/Makefile
> +++ b/tools/testing/selftests/x86/Makefile
> @@ -12,7 +12,7 @@ CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh "$(CC)" trivial_program.c -no-pie)
>
> TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
> check_initial_reg_state sigreturn iopl ioperm \
> - test_vsyscall mov_ss_trap \
> + test_vsyscall mov_ss_trap test_sigtrap_handler \
> syscall_arg_fault fsgsbase_restore sigaltstack
> TARGETS_C_BOTHBITS += nx_stack
> TARGETS_C_32BIT_ONLY := entry_from_vm86 test_syscall_vdso unwind_vdso \
> diff --git a/tools/testing/selftests/x86/test_sigtrap_handler.c b/tools/testing/selftests/x86/test_sigtrap_handler.c
> new file mode 100644
> index 000000000000..9c5c2cf0cf88
> --- /dev/null
> +++ b/tools/testing/selftests/x86/test_sigtrap_handler.c
> @@ -0,0 +1,80 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
Curious about your use of GPL-2.0-or-later?
All the files in this directory use GPL-2.0-only or GPL-2.0.
> +/*
> + * Copyright (C) 2025 Intel Corporation
> + */
> +#define _GNU_SOURCE
> +
> +#include <err.h>
> +#include <signal.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/ucontext.h>
> +
> +#ifdef __x86_64__
> +# define REG_IP REG_RIP
> +#else
> +# define REG_IP REG_EIP
> +#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");
> +
> + return;
> +}
> +
> +static unsigned int loop_count_on_same_ip;
> +
> +static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
> +{
> + ucontext_t *ctx = (ucontext_t *)ctx_void;
> + static unsigned long last_trap_ip;
> +
> + if (last_trap_ip == ctx->uc_mcontext.gregs[REG_IP]) {
> + printf("trapped on %016lx\n", last_trap_ip);
> +
> + if (++loop_count_on_same_ip > 10) {
> + printf("trap loop detected, test failed\n");
> + exit(2);
> + }
Most of the x86 selftests use the ksft_exit_fail_msg(), ksft_print_msg()
or [RUN, FAIL, OK] style for error messages and other informational prints.
> +
> + return;
> + }
> +
> + loop_count_on_same_ip = 0;
> + last_trap_ip = ctx->uc_mcontext.gregs[REG_IP];
> + printf("trapped on %016lx\n", last_trap_ip);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + sethandler(SIGTRAP, sigtrap, 0);
> +
I would suggest a comment here to explain what the following assembly
code is supposed to do. It isn't obvious from a cursory look.
> + asm volatile(
> +#ifdef __x86_64__
> + /* Avoid clobbering the redzone */
> + "sub $128, %rsp\n\t"
> +#endif
> + "push $0x302\n\t"
> + "popf\n\t"
> + "nop\n\t"
> + "nop\n\t"
> + "push $0x202\n\t"
> + "popf\n\t"
> +#ifdef __x86_64__
> + "add $128, %rsp\n\t"
> +#endif
> + );
> +
> + printf("test passed\n");
> + return 0;
> +}
>
> base-commit: 485d11d84a2452ac16466cc7ae041c93d38929bc
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-05-31 0:15 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-05-30 23:07 [PATCH v1 1/1] selftests/x86: Add a test to detect infinite sigtrap handler loop Xin Li (Intel)
2025-05-31 0:14 ` Sohil Mehta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®