diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-04-04 01:36:44 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2024-04-08 19:27:05 +0200 |
commit | 1e3ad78334a69b36e107232e337f9d693dcc9df2 (patch) | |
tree | 11162955093106a59ca3825365580797e0aff750 /arch/x86/entry/syscall_64.c | |
parent | x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file (diff) | |
download | linux-1e3ad78334a69b36e107232e337f9d693dcc9df2.tar.xz linux-1e3ad78334a69b36e107232e337f9d693dcc9df2.zip |
x86/syscall: Don't force use of indirect calls for system calls
Make <asm/syscall.h> build a switch statement instead, and the compiler can
either decide to generate an indirect jump, or - more likely these days due
to mitigations - just a series of conditional branches.
Yes, the conditional branches also have branch prediction, but the branch
prediction is much more controlled, in that it just causes speculatively
running the wrong system call (harmless), rather than speculatively running
possibly wrong random less controlled code gadgets.
This doesn't mitigate other indirect calls, but the system call indirection
is the first and most easily triggered case.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Daniel Sneddon <daniel.sneddon@linux.intel.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Josh Poimboeuf <jpoimboe@kernel.org>
Diffstat (limited to 'arch/x86/entry/syscall_64.c')
-rw-r--r-- | arch/x86/entry/syscall_64.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c index be120eec1fc9..33b3f09e6f15 100644 --- a/arch/x86/entry/syscall_64.c +++ b/arch/x86/entry/syscall_64.c @@ -11,8 +11,23 @@ #include <asm/syscalls_64.h> #undef __SYSCALL +/* + * The sys_call_table[] is no longer used for system calls, but + * kernel/trace/trace_syscalls.c still wants to know the system + * call address. + */ #define __SYSCALL(nr, sym) __x64_##sym, - -asmlinkage const sys_call_ptr_t sys_call_table[] = { +const sys_call_ptr_t sys_call_table[] = { #include <asm/syscalls_64.h> }; +#undef __SYSCALL + +#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs); + +long x64_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include <asm/syscalls_64.h> + default: return __x64_sys_ni_syscall(regs); + } +}; |