Re: [PATCH v16 18/18] arm64: vdso: Expose sigreturn address on vdso to the kernel
From: Jinjie Ruan <hidden>
Date: 2026-07-09 08:15:25
Also in:
linux-alpha, linux-m68k, linux-mips, linux-mm, linux-riscv, linux-s390, linux-sh, linux-um, lkml, loongarch
Subsystem:
arm64 port (aarch64 architecture), the rest · Maintainers:
Catalin Marinas, Will Deacon, Linus Torvalds
On 7/9/2026 3:17 PM, Thomas Weißschuh wrote:
On Thu, Jul 09, 2026 at 02:37:05PM +0800, Jinjie Ruan wrote:quoted
On 6/30/2026 11:32 PM, Thomas Weißschuh wrote:quoted
On Mon, Jun 29, 2026 at 09:06:16PM +0800, Jinjie Ruan wrote:(..)quoted
quoted
quoted
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().It seems that the modification of __kernel_rt_sigreturn() is not recommendedFor the changes to the object code of the function this is obvious and well explained in the comments. Such a label however would not change the object code of the function. In fact it would not change any bit whatsoever in the final vDSO, save for a new build ID.
Yes, and using labels is easier to maintain than hardcoding offsets directly. Similar to the code below?
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig@@ -86,6 +86,7 @@ config ARM64 select ARCH_SUPPORTS_SCHED_SMT select ARCH_SUPPORTS_SCHED_CLUSTER select ARCH_SUPPORTS_SCHED_MC + select ARCH_SUPPORTS_SYSCALL_USER_DISPATCH select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT select ARCH_WANT_DEFAULT_BPF_JIT
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index d2779d604c7b..a8b232c5c6d9 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h@@ -293,6 +293,7 @@ static inline int arch_check_elf(void *ehdr, boolhas_interp,
return 0;
}
+extern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
#endif /* !__ASSEMBLER__ */
#endifdiff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 592dd8668de4..609d7bcd8308 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,
sigreturn_landing_pad);
+
+ return regs->pc == sigtramp;
+}diff --git a/arch/arm64/kernel/vdso/sigreturn.Sb/arch/arm64/kernel/vdso/sigreturn.S index 0e18729abc3b..8d2d413ff45e 100644
--- a/arch/arm64/kernel/vdso/sigreturn.S
+++ b/arch/arm64/kernel/vdso/sigreturn.S@@ -73,6 +73,7 @@ SYM_CODE_START(__kernel_rt_sigreturn) mov x8, #__NR_rt_sigreturn // PLEASE DO NOT MODIFY svc #0 + SYM_INNER_LABEL(__sigreturn_landing_pad, SYM_L_GLOBAL) // PLEASE DO NOT MODIFY // .cfi_endproc SYM_CODE_END(__kernel_rt_sigreturn)
diff --git a/arch/arm64/kernel/vdso/vdso.lds.Sb/arch/arm64/kernel/vdso/vdso.lds.S index 52314be29191..5fee2927e4c5 100644
--- a/arch/arm64/kernel/vdso/vdso.lds.S
+++ b/arch/arm64/kernel/vdso/vdso.lds.S@@ -104,6 +104,7 @@ VERSION __kernel_clock_gettime; __kernel_clock_getres; __kernel_getrandom; + __sigreturn_landing_pad; local: *; }; }
@@ -112,3 +113,4 @@ VERSION * Make the sigreturn code visible to the kernel. */ VDSO_sigtramp = __kernel_rt_sigreturn; +VDSO_sigreturn_landing_pad = __sigreturn_landing_pad;
Thomas