Re: [patch 03/18] entry: Provide [syscall_]enter_from_user_mode_randomize_stack()
Jinjie Ruan <[email protected]> Thu, 9 Jul 2026 11:46:07 +0800
| Newsgroups | org.kernel.vger.linux-hexagon,dev.linux.lists.loongarch,org.infradead.lists.linux-riscv,org.infradead.lists.linux-snps-arc,org.infradead.lists.linux-um,org.kernel.vger.linux-alpha,org.kernel.vger.linux-arch,org.kernel.vger.linux-csky,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-m68k,org.kernel.vger.linux-mips,org.kernel.vger.linux-openrisc,org.kernel.vger.linux-parisc,org.kernel.vger.linux-s390,org.kernel.vger.linux-sh,org.kernel.vger.sparclinux,org.ozlabs.lists.linuxppc-dev |
|---|---|
| Message-ID | <[email protected]> |
On 7/8/2026 3:06 AM, Thomas Gleixner wrote: > Randomizing the syscall stack can only happen after state is established > via enter_from_user_mode() or syscall_enter_from_user_mode(). The earlier > it happens the better. > > Provide two new macros to consolidate that: > > - enter_from_user_mode_randomize_stack() > enter_from_user_mode(); > add_random_kstack_offset_irqsoff(); > > - syscall_enter_from_user_mode_randomize_stack() > enter_from_user_mode_randomize_stack(); > syscall_enter_from_user_mode_work(); > > to reduce boiler plate code. > > Those are macros and not inline functions as the latter would limit the > stack randomization scope to the inline function itself. > > Signed-off-by: Thomas Gleixner <[email protected]> > --- > include/linux/entry-common.h | 56 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 56 insertions(+) > > --- a/include/linux/entry-common.h > +++ b/include/linux/entry-common.h > @@ -6,6 +6,7 @@ > #include <linux/irq-entry-common.h> > #include <linux/livepatch.h> > #include <linux/ptrace.h> > +#include <linux/randomize_kstack.h> > #include <linux/resume_user_mode.h> > #include <linux/seccomp.h> > #include <linux/sched.h> > @@ -150,6 +151,61 @@ static __always_inline long syscall_ente > } > > /** > + * enter_from_user_mode_randomize_stack - Establish state and add stack randomization > + * before invoking syscall_enter_from_user_mode_work() > + * @regs: Pointer to currents pt_regs > + * > + * Invoked from architecture specific syscall entry code with interrupts > + * disabled. The calling code has to be non-instrumentable. When the function > + * returns all state is correct, interrupts are still disabled and the > + * subsequent functions can be instrumented. > + * > + * Implemented as a macro so that the stack randomization is effective > + * throughout the function in which it is invoked. An inline would only make it > + * effective in the scope of the inline function. > + */ > +#define enter_from_user_mode_randomize_stack(regs) \ > +do { \ > + enter_from_user_mode(regs); \ > + instrumentation_begin(); \ > + add_random_kstack_offset_irqsoff(); \ > + instrumentation_end(); \ > +} while (0) Perhaps this new function can also be reused when the ARM64 is switched to the generic entry as the irq also disabled now. --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -64,7 +64,7 @@ static void noinstr arm64_exit_to_kernel_mode(struct pt_regs *regs, static __always_inline void arm64_syscall_enter_from_user_mode(struct pt_regs *regs) { - enter_from_user_mode(regs); + enter_from_user_mode_randomize_stack(regs); mte_disable_tco_entry(current); sme_enter_from_user_mode(); } diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index e0a98fac3b85..42ac02573b66 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -6,7 +6,6 @@ #include <linux/errno.h> #include <linux/nospec.h> #include <linux/ptrace.h> -#include <linux/randomize_kstack.h> #include <linux/syscalls.h> #include <asm/debug-monitors.h> @@ -42,8 +41,6 @@ static void invoke_syscall(struct pt_regs *regs, unsigned int scno, { long ret; - add_random_kstack_offset(); - if (likely(scno < sc_nr)) { syscall_fn_t syscall_fn; syscall_fn = syscall_table[array_index_nospec(scno, sc_nr)]; > + > +/** > + * syscall_enter_from_user_mode_randomize_stack - Establish state and check and handle work > + * before invoking a syscall > + * @regs: Pointer to currents pt_regs > + * @syscall: The syscall number > + * > + * Invoked from architecture specific syscall entry code with interrupts > + * disabled. The calling code has to be non-instrumentable. When the > + * function returns all state is correct, interrupts are enabled and the > + * subsequent functions can be instrumented. > + * > + * This is the combination of enter_from_user_mode_randomize_stack() and > + * syscall_enter_from_user_mode_work() to be used when there is no > + * architecture specific work to be done between the two. > + * > + * Returns: The original or a modified syscall number. See > + * syscall_enter_from_user_mode_work() for further explanation. > + * > + * Implemented as a macro to make stack randomization effective in the calling > + * scope. > + */ > +#define syscall_enter_from_user_mode_randomize_stack(regs, syscall) \ > +({ \ > + enter_from_user_mode_randomize_stack(regs); \ > + \ > + instrumentation_begin(); \ > + local_irq_enable(); \ > + long _ret = syscall_enter_from_user_mode_work(regs, syscall); \ > + instrumentation_end(); \ > + \ > + _ret; \ > +}) > + > +/** > * syscall_enter_from_user_mode - Establish state and check and handle work > * before invoking a syscall > * @regs: Pointer to currents pt_regs >