Re: [PATCH v16 18/18] arm64: vdso: Expose sigreturn address on vdso to the kernel
Thomas Weißschuh <[email protected]> Tue, 30 Jun 2026 17:32:04 +0200
| Newsgroups | gmane.linux.ports.m68k,gmane.linux.ports.alpha,gmane.linux.kernel,gmane.linux.ports.arm.kernel,gmane.linux.kernel.mm,gmane.linux.ports.mips,gmane.linux.ports.parisc,gmane.linux.ports.ppc64.devel,gmane.linux.ports.riscv,gmane.linux.ports.sh.devel,gmane.linux.uml.devel |
|---|---|
| Message-ID | <20260630172619-6c78c2e2-c2d3-44be-88e6-6c82de12baf4@linutronix.de> |
On Mon, Jun 29, 2026 at 09:06:16PM +0800, Jinjie Ruan wrote: > 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 <[email protected]> > Suggested-by: kemal <[email protected]> > Signed-off-by: Jinjie Ruan <[email protected]> > --- > 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? > /* 1GB of VA */ > #ifdef CONFIG_COMPAT > diff --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