Commit ec5d7c25 authored by David Woodhouse's avatar David Woodhouse Committed by Kleber Sacilotto de Souza

x86/retpoline/entry: Convert entry assembler indirect jumps

CVE-2017-5715 (Spectre v2 retpoline)

commit 2641f08b upstream.

Convert indirect jumps in core 32/64bit entry assembler code to use
non-speculative sequences when CONFIG_RETPOLINE is enabled.

Don't use CALL_NOSPEC in entry_SYSCALL_64_fastpath because the return
address after the 'call' instruction must be *precisely* at the
.Lentry_SYSCALL_64_after_fastpath label for stub_ptregs_64 to work,
and the use of alternatives will mess that up unless we play horrid
games to prepend with NOPs and make the variants the same length. It's
not worth it; in the case where we ALTERNATIVE out the retpoline, the
first instruction at __x86.indirect_thunk.rax is going to be a bare
jmp *%rax anyway.
Signed-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Acked-by: default avatarIngo Molnar <mingo@kernel.org>
Acked-by: default avatarArjan van de Ven <arjan@linux.intel.com>
Cc: gnomes@lxorguk.ukuu.org.uk
Cc: Rik van Riel <riel@redhat.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jiri Kosina <jikos@kernel.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Kees Cook <keescook@google.com>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
Cc: Paul Turner <pjt@google.com>
Link: https://lkml.kernel.org/r/1515707194-20531-7-git-send-email-dwmw@amazon.co.ukSigned-off-by: default avatarDavid Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: default avatarRazvan Ghitulete <rga@amazon.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit 11ed3fa6214dc86c2e12331f0864260c76f01328)
Signed-off-by: default avatarAndy Whitcroft <apw@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent 25493a7e
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/alternative-asm.h> #include <asm/alternative-asm.h>
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/smap.h> #include <asm/smap.h>
#include <asm/nospec-branch.h>
.section .entry.text, "ax" .section .entry.text, "ax"
...@@ -226,7 +227,8 @@ ENTRY(ret_from_kernel_thread) ...@@ -226,7 +227,8 @@ ENTRY(ret_from_kernel_thread)
pushl $0x0202 # Reset kernel eflags pushl $0x0202 # Reset kernel eflags
popfl popfl
movl PT_EBP(%esp), %eax movl PT_EBP(%esp), %eax
call *PT_EBX(%esp) movl PT_EBX(%esp), %edx
CALL_NOSPEC %edx
movl $0, PT_EAX(%esp) movl $0, PT_EAX(%esp)
/* /*
...@@ -938,7 +940,7 @@ error_code: ...@@ -938,7 +940,7 @@ error_code:
movl %ecx, %es movl %ecx, %es
TRACE_IRQS_OFF TRACE_IRQS_OFF
movl %esp, %eax # pt_regs pointer movl %esp, %eax # pt_regs pointer
call *%edi CALL_NOSPEC %edi
jmp ret_from_exception jmp ret_from_exception
END(page_fault) END(page_fault)
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/smap.h> #include <asm/smap.h>
#include <asm/pgtable_types.h> #include <asm/pgtable_types.h>
#include <asm/kaiser.h> #include <asm/kaiser.h>
#include <asm/nospec-branch.h>
#include <linux/err.h> #include <linux/err.h>
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */ /* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
...@@ -184,7 +185,13 @@ entry_SYSCALL_64_fastpath: ...@@ -184,7 +185,13 @@ entry_SYSCALL_64_fastpath:
#endif #endif
ja 1f /* return -ENOSYS (already in pt_regs->ax) */ ja 1f /* return -ENOSYS (already in pt_regs->ax) */
movq %r10, %rcx movq %r10, %rcx
#ifdef CONFIG_RETPOLINE
movq sys_call_table(, %rax, 8), %rax
call __x86_indirect_thunk_rax
#else
call *sys_call_table(, %rax, 8) call *sys_call_table(, %rax, 8)
#endif
movq %rax, RAX(%rsp) movq %rax, RAX(%rsp)
1: 1:
/* /*
...@@ -276,7 +283,12 @@ tracesys_phase2: ...@@ -276,7 +283,12 @@ tracesys_phase2:
#endif #endif
ja 1f /* return -ENOSYS (already in pt_regs->ax) */ ja 1f /* return -ENOSYS (already in pt_regs->ax) */
movq %r10, %rcx /* fixup for C */ movq %r10, %rcx /* fixup for C */
#ifdef CONFIG_RETPOLINE
movq sys_call_table(, %rax, 8), %rax
call __x86_indirect_thunk_rax
#else
call *sys_call_table(, %rax, 8) call *sys_call_table(, %rax, 8)
#endif
movq %rax, RAX(%rsp) movq %rax, RAX(%rsp)
1: 1:
/* Use IRET because user could have changed pt_regs->foo */ /* Use IRET because user could have changed pt_regs->foo */
...@@ -491,7 +503,7 @@ ENTRY(ret_from_fork) ...@@ -491,7 +503,7 @@ ENTRY(ret_from_fork)
* nb: we depend on RESTORE_EXTRA_REGS above * nb: we depend on RESTORE_EXTRA_REGS above
*/ */
movq %rbp, %rdi movq %rbp, %rdi
call *%rbx CALL_NOSPEC %rbx
movl $0, RAX(%rsp) movl $0, RAX(%rsp)
RESTORE_EXTRA_REGS RESTORE_EXTRA_REGS
jmp int_ret_from_sys_call jmp int_ret_from_sys_call
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment