Re: [PATCH v16 18/18] arm64: vdso: Expose sigreturn address on vdso to the kernel
From: Thomas Weißschuh <hidden>
Date: 2026-06-30 15:32:08
Also in:
linux-alpha, linux-m68k, linux-mips, linux-mm, linux-riscv, linux-s390, linux-sh, linux-um, lkml, loongarch
On Mon, Jun 29, 2026 at 09:06:16PM +0800, Jinjie Ruan wrote:
quoted hunk ↗ jump to hunk
Syscall User Dispatch (SUD) requires the signal trampoline code to not be intercepted. This is necessary to support returning with a locked selector while avoiding infinite recursion back into the signal handler. Implement arch_syscall_is_vdso_sigreturn() for arm64 to support this exclusion mechanism. For native 64-bit tasks, it checks whether the current PC matches the 'svc #0' instruction inside the vDSO sigreturn trampoline. SYM_CODE_START(__kernel_rt_sigreturn) mov x8, #__NR_rt_sigreturn svc #0 SYM_CODE_END(__kernel_rt_sigreturn) For COMPAT tasks, it verifies if the instruction falls within the architecture's 'sigpage' range, allowing the kernel to safely bypass dispatching syscalls originating from these areas back to userspace. Suggested-by: Kevin Brodsky <redacted> Suggested-by: kemal <redacted> Signed-off-by: Jinjie Ruan <redacted> --- arch/arm64/include/asm/elf.h | 1 + arch/arm64/kernel/vdso.c | 16 ++++++++++++++++ 2 files changed, 17 insertions(+)diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index d2779d604c7b..f43d4dea916a 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h@@ -185,6 +185,7 @@ do { \ struct linux_binprm; extern int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp); +extern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
A header for that?
quoted hunk ↗ jump to hunk
/* 1GB of VA */ #ifdef CONFIG_COMPATdiff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 592dd8668de4..5a0314a3c26e 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c@@ -343,3 +343,19 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) return ret; } + +bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs) +{ + unsigned long sigtramp; + +#ifdef CONFIG_COMPAT + if (is_compat_task()) { + unsigned long sigpage = (unsigned long)current->mm->context.sigpage; + + return regs->pc >= sigpage && regs->pc < (sigpage + PAGE_SIZE); + } +#endif + sigtramp = (unsigned long)VDSO_SYMBOL(current->mm->context.vdso, sigtramp); + + return regs->pc == (sigtramp + 8);
Instead of hardcoding 'sigtramp + 8' you could add a new label to the 'svc #0' instruction and use that with VDSO_SYMBOL(). Thomas