From 2c79c9951b2d6c90d33f2f1d4e896f3fd2f87ff9 Mon Sep 17 00:00:00 2001 From: raiden00pl Date: Mon, 10 Aug 2026 12:35:23 +0200 Subject: [PATCH] arch/x86_64: run the signal trampoline on the thread kernel stack For a thread interrupted in user mode the trampoline ran on the user stack, where the signal handler then grows over its frame. Run it on the thread kernel stack, unused while the thread is in user mode. The stack cannot be selected from the saved CS: up_initial_state() records the caller CS, a kernel selector even for user threads. Signed-off-by: raiden00pl Assisted-by: Claude Code --- .../src/intel64/intel64_schedulesigaction.c | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/x86_64/src/intel64/intel64_schedulesigaction.c b/arch/x86_64/src/intel64/intel64_schedulesigaction.c index 2bd5cc52e53..7b8fae360b5 100644 --- a/arch/x86_64/src/intel64/intel64_schedulesigaction.c +++ b/arch/x86_64/src/intel64/intel64_schedulesigaction.c @@ -74,6 +74,8 @@ void up_schedule_sigaction(struct tcb_s *tcb) { + uint64_t sp = tcb->xcp.regs[REG_RSP]; + sinfo("tcb=%p, rtcb=%p current_regs=%p\n", tcb, this_task(), this_task()->xcp.regs); @@ -83,7 +85,7 @@ void up_schedule_sigaction(struct tcb_s *tcb) */ tcb->xcp.saved_rip = tcb->xcp.regs[REG_RIP]; - tcb->xcp.saved_rsp = tcb->xcp.regs[REG_RSP]; + tcb->xcp.saved_rsp = sp; tcb->xcp.saved_rflags = tcb->xcp.regs[REG_RFLAGS]; /* Then set up to vector to the trampoline with interrupts @@ -91,6 +93,21 @@ void up_schedule_sigaction(struct tcb_s *tcb) */ tcb->xcp.regs[REG_RIP] = (uint64_t)x86_64_sigdeliver; - tcb->xcp.regs[REG_RSP] = tcb->xcp.regs[REG_RSP] - 8; tcb->xcp.regs[REG_RFLAGS] = 0; + +#ifdef CONFIG_ARCH_KERNEL_STACK + /* Run the trampoline on the thread kernel stack when the thread was + * interrupted in user mode: the signal handler runs on the user + * stack and would overwrite the trampoline frame there. + */ + + if (tcb->xcp.kstack != NULL && + (sp < (uint64_t)tcb->xcp.kstack || sp > (uint64_t)tcb->xcp.ktopstk)) + { + tcb->xcp.saved_ursp = sp; + sp = (uint64_t)tcb->xcp.ktopstk; + } +#endif + + tcb->xcp.regs[REG_RSP] = sp - 8; }