mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: David Laight <david.laight.linux@gmail.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: x86@kernel.org, linux-kernel@vger.kernel.org,
	jpoimboe@kernel.org, leitao@debian.org, keescook@chromium.org,
	hpa@zytor.com
Subject: Re: [PATCH 4/6] x86_64/entry: Mark all syscalls __noendbr
Date: Mon, 2 Nov 2026 17:06:30 +0000	[thread overview]
Message-ID: <20261102170630.1dfc00eb@pumpkin> (raw)
In-Reply-To: <20261102114000.771366690@infradead.org>

On Mon, 02 Nov 2026 12:25:53 +0100
Peter Zijlstra <peterz@infradead.org> wrote:

> Since system call dispatch is now strictly through direct calls, there is no
> reason for the syscalls to be called indirectly. Mark them all __noendbr.
> 
> Notably, the sys_call_table[] is purely a lookup for tracing and the like,
> nobody actually (should) dispatch anything through it, and with this we make
> sure nobody *can*.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
>  arch/x86/entry/syscall_32.c            |    5 +++--
>  arch/x86/entry/syscall_64.c            |    7 ++++---
>  arch/x86/include/asm/syscall_wrapper.h |   23 ++++++++++++-----------
>  tools/objtool/check.c                  |    9 ++++++++-
>  4 files changed, 27 insertions(+), 17 deletions(-)
> 
> --- a/arch/x86/entry/syscall_32.c
> +++ b/arch/x86/entry/syscall_32.c
> @@ -12,6 +12,7 @@
>  #include <asm/traps.h>
>  #include <asm/cpufeature.h>
>  #include <asm/syscall.h>
> +#include <asm/ibt.h>
>  
>  #ifdef CONFIG_IA32_EMULATION
>  #define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, compat)
> @@ -19,8 +20,8 @@
>  #define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, native)
>  #endif
>  
> -#define __SYSCALL(nr, sym) extern long __ia32_##sym(const struct pt_regs *);
> -#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __ia32_##sym(const struct pt_regs *);
> +#define __SYSCALL(nr, sym) extern __noendbr long __ia32_##sym(const struct pt_regs *);
> +#define __SYSCALL_NORETURN(nr, sym) extern __noendbr long __noreturn __ia32_##sym(const struct pt_regs *);
>  #include <asm/syscalls_32.h>
>  #undef  __SYSCALL
>  
> --- a/arch/x86/entry/syscall_64.c
> +++ b/arch/x86/entry/syscall_64.c
> @@ -8,9 +8,10 @@
>  #include <linux/entry-common.h>
>  #include <linux/nospec.h>
>  #include <asm/syscall.h>
> +#include <asm/ibt.h>
>  
> -#define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
> -#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
> +#define __SYSCALL(nr, sym) extern __noendbr long __x64_##sym(const struct pt_regs *);
> +#define __SYSCALL_NORETURN(nr, sym) extern __noendbr long __noreturn __x64_##sym(const struct pt_regs *);
>  #include <asm/syscalls_64.h>
>  #ifdef CONFIG_X86_X32_ABI
>  #include <asm/syscalls_x32.h>
> @@ -25,7 +26,7 @@
>   * kernel/trace/trace_syscalls.c still wants to know the system
>   * call address.
>   */
> -#define __SYSCALL(nr, sym) __x64_##sym,
> +#define __SYSCALL(nr, sym) (void *)&__x64_##sym,
>  const sys_call_ptr_t sys_call_table[] = {
>  #include <asm/syscalls_64.h>
>  };
> --- a/arch/x86/include/asm/syscall_wrapper.h
> +++ b/arch/x86/include/asm/syscall_wrapper.h
> @@ -7,9 +7,10 @@
>  #define _ASM_X86_SYSCALL_WRAPPER_H
>  
>  #include <asm/ptrace.h>
> +#include <asm/ibt.h>
>  
> -extern long __x64_sys_ni_syscall(const struct pt_regs *regs);
> -extern long __ia32_sys_ni_syscall(const struct pt_regs *regs);
> +extern __noendbr long __x64_sys_ni_syscall(const struct pt_regs *regs);
> +extern __noendbr long __ia32_sys_ni_syscall(const struct pt_regs *regs);
>  
>  /*
>   * Instead of the generic __SYSCALL_DEFINEx() definition, the x86 version takes
> @@ -83,22 +84,22 @@ extern long __ia32_sys_ni_syscall(const
>  			__MAP(x, __SC_TYPE, __VA_ARGS__))		\
>  
>  #define __SYS_STUB0(abi, name)						\
> -	long __##abi##_##name(const struct pt_regs *regs);		\
> +	long __noendbr __##abi##_##name(const struct pt_regs *regs);	\
>  	ALLOW_ERROR_INJECTION(__##abi##_##name, ERRNO);			\
> -	long __##abi##_##name(const struct pt_regs *regs)		\
> +	long __noendbr __##abi##_##name(const struct pt_regs *regs)	\
>  		__alias(__do_##name);
>  
>  #define __SYS_STUBx(abi, name, ...)					\
> -	long __##abi##_##name(const struct pt_regs *regs);		\
> +	long __noendbr __##abi##_##name(const struct pt_regs *regs);	\
>  	ALLOW_ERROR_INJECTION(__##abi##_##name, ERRNO);			\
> -	long __##abi##_##name(const struct pt_regs *regs)		\
> +	long __noendbr __##abi##_##name(const struct pt_regs *regs)	\
>  	{								\
>  		return __se_##name(__VA_ARGS__);			\
>  	}
>  
>  #define __COND_SYSCALL(abi, name)					\
> -	__weak long __##abi##_##name(const struct pt_regs *__unused);	\
> -	__weak long __##abi##_##name(const struct pt_regs *__unused)	\
> +	__weak long __noendbr __##abi##_##name(const struct pt_regs *__unused);	\
> +	__weak long __noendbr __##abi##_##name(const struct pt_regs *__unused)	\
>  	{								\
>  		return sys_ni_syscall();				\
>  	}
> @@ -257,8 +258,8 @@ extern long __ia32_sys_ni_syscall(const
>   * For VSYSCALLS, we need to declare these three syscalls with the new
>   * pt_regs-based calling convention for in-kernel use.
>   */
> -long __x64_sys_getcpu(const struct pt_regs *regs);
> -long __x64_sys_gettimeofday(const struct pt_regs *regs);
> -long __x64_sys_time(const struct pt_regs *regs);
> +long __noendbr __x64_sys_getcpu(const struct pt_regs *regs);
> +long __noendbr __x64_sys_gettimeofday(const struct pt_regs *regs);
> +long __noendbr __x64_sys_time(const struct pt_regs *regs);
>  
>  #endif /* _ASM_X86_SYSCALL_WRAPPER_H */
> --- a/tools/objtool/check.c
> +++ b/tools/objtool/check.c
> @@ -4672,8 +4672,15 @@ static int validate_ibt(struct objtool_f
>  		    !strcmp(sec->name, "__patchable_function_entries"))
>  			continue;
>  
> -		for_each_reloc(sec->rsec, reloc)
> +		for_each_reloc(sec->rsec, reloc) {
> +			struct symbol *sym = find_symbol_containing(reloc->sec->base,
> +								    reloc_offset(reloc));
> +
> +			if (sym && !strcmp(sym->name, "sys_call_table"))
> +				continue;

Does that slow things down somewhat?
Could you do it the other way around??
So remember the bounds of sys_call_table and just check whether the relocation
in inside it.

Try building x86-64 allyesconfig :-)

David

> +
>  			warnings += validate_ibt_data_reloc(file, reloc);
> +		}
>  	}
>  
>  	return warnings;
> 
> 
> 


  reply	other threads:[~2026-11-02 17:06 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 11:25 [PATCH 0/6] x86: Harden syscall dispatch Peter Zijlstra
2026-11-02 11:25 ` [PATCH 1/6] x86_64/entry: Unconditionally use -fno-jump-table Peter Zijlstra
2026-11-02 14:28   ` Breno Leitao
2026-11-02 11:25 ` [PATCH 2/6] objtool: Add instrumentation_weak() Peter Zijlstra
2026-11-02 11:25 ` [PATCH 3/6] x86_64/entry: Make syscall dispatch noinstr Peter Zijlstra
2026-11-02 11:25 ` [PATCH 4/6] x86_64/entry: Mark all syscalls __noendbr Peter Zijlstra
2026-11-02 17:06   ` David Laight [this message]
2026-11-03  8:51     ` Peter Zijlstra
2026-11-02 11:25 ` [PATCH 5/6] objtool: Allow EXPORT_SYMBOL() of __noendbr functions Peter Zijlstra
2026-11-02 11:25 ` [PATCH 6/6] x86_64/entry: Mark C noinstr __noendbr Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261102170630.1dfc00eb@pumpkin \
    --to=david.laight.linux@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jpoimboe@kernel.org \
    --cc=keescook@chromium.org \
    --cc=leitao@debian.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®