a0f7ab8a6a
cherry-pick from upstream 4.14
135 lines
3.8 KiB
Diff
135 lines
3.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Andy Lutomirski <luto@kernel.org>
|
|
Date: Thu, 2 Nov 2017 00:58:59 -0700
|
|
Subject: [PATCH] x86/entry/64: Split the IRET-to-user and IRET-to-kernel paths
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
CVE-2017-5754
|
|
|
|
These code paths will diverge soon.
|
|
|
|
Signed-off-by: Andy Lutomirski <luto@kernel.org>
|
|
Cc: Borislav Petkov <bpetkov@suse.de>
|
|
Cc: Brian Gerst <brgerst@gmail.com>
|
|
Cc: Dave Hansen <dave.hansen@intel.com>
|
|
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
Cc: Thomas Gleixner <tglx@linutronix.de>
|
|
Link: http://lkml.kernel.org/r/dccf8c7b3750199b4b30383c812d4e2931811509.1509609304.git.luto@kernel.org
|
|
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
(cherry picked from commit 26c4ef9c49d8a0341f6d97ce2cfdd55d1236ed29)
|
|
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
|
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
|
|
(cherry picked from commit 64adfba0aeb668304d171c383ac80b22158ec128)
|
|
Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
|
|
---
|
|
arch/x86/entry/entry_64.S | 34 +++++++++++++++++++++++++---------
|
|
arch/x86/entry/entry_64_compat.S | 2 +-
|
|
arch/x86/kernel/head_64.S | 2 +-
|
|
3 files changed, 27 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
|
|
index fac354ddf056..e546441fbec3 100644
|
|
--- a/arch/x86/entry/entry_64.S
|
|
+++ b/arch/x86/entry/entry_64.S
|
|
@@ -321,7 +321,7 @@ syscall_return_via_sysret:
|
|
|
|
opportunistic_sysret_failed:
|
|
SWAPGS
|
|
- jmp restore_regs_and_iret
|
|
+ jmp restore_regs_and_return_to_usermode
|
|
END(entry_SYSCALL_64)
|
|
|
|
ENTRY(stub_ptregs_64)
|
|
@@ -423,7 +423,7 @@ ENTRY(ret_from_fork)
|
|
call syscall_return_slowpath /* returns with IRQs disabled */
|
|
TRACE_IRQS_ON /* user mode is traced as IRQS on */
|
|
SWAPGS
|
|
- jmp restore_regs_and_iret
|
|
+ jmp restore_regs_and_return_to_usermode
|
|
|
|
1:
|
|
/* kernel thread */
|
|
@@ -612,7 +612,20 @@ GLOBAL(retint_user)
|
|
call prepare_exit_to_usermode
|
|
TRACE_IRQS_IRETQ
|
|
SWAPGS
|
|
- jmp restore_regs_and_iret
|
|
+
|
|
+GLOBAL(restore_regs_and_return_to_usermode)
|
|
+#ifdef CONFIG_DEBUG_ENTRY
|
|
+ /* Assert that pt_regs indicates user mode. */
|
|
+ testl $3, CS(%rsp)
|
|
+ jnz 1f
|
|
+ ud2
|
|
+1:
|
|
+#endif
|
|
+ RESTORE_EXTRA_REGS
|
|
+ RESTORE_C_REGS
|
|
+ REMOVE_PT_GPREGS_FROM_STACK 8
|
|
+ INTERRUPT_RETURN
|
|
+
|
|
|
|
/* Returning to kernel space */
|
|
retint_kernel:
|
|
@@ -632,11 +645,14 @@ retint_kernel:
|
|
*/
|
|
TRACE_IRQS_IRETQ
|
|
|
|
-/*
|
|
- * At this label, code paths which return to kernel and to user,
|
|
- * which come from interrupts/exception and from syscalls, merge.
|
|
- */
|
|
-GLOBAL(restore_regs_and_iret)
|
|
+GLOBAL(restore_regs_and_return_to_kernel)
|
|
+#ifdef CONFIG_DEBUG_ENTRY
|
|
+ /* Assert that pt_regs indicates kernel mode. */
|
|
+ testl $3, CS(%rsp)
|
|
+ jz 1f
|
|
+ ud2
|
|
+1:
|
|
+#endif
|
|
RESTORE_EXTRA_REGS
|
|
RESTORE_C_REGS
|
|
REMOVE_PT_GPREGS_FROM_STACK 8
|
|
@@ -1340,7 +1356,7 @@ ENTRY(nmi)
|
|
* work, because we don't want to enable interrupts.
|
|
*/
|
|
SWAPGS
|
|
- jmp restore_regs_and_iret
|
|
+ jmp restore_regs_and_return_to_usermode
|
|
|
|
.Lnmi_from_kernel:
|
|
/*
|
|
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
|
|
index d8468ba24be0..2b3a88feaa2b 100644
|
|
--- a/arch/x86/entry/entry_64_compat.S
|
|
+++ b/arch/x86/entry/entry_64_compat.S
|
|
@@ -337,7 +337,7 @@ ENTRY(entry_INT80_compat)
|
|
/* Go back to user mode. */
|
|
TRACE_IRQS_ON
|
|
SWAPGS
|
|
- jmp restore_regs_and_iret
|
|
+ jmp restore_regs_and_return_to_usermode
|
|
END(entry_INT80_compat)
|
|
|
|
ALIGN
|
|
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
|
|
index 4117c1e0b3d2..e785734980ad 100644
|
|
--- a/arch/x86/kernel/head_64.S
|
|
+++ b/arch/x86/kernel/head_64.S
|
|
@@ -311,7 +311,7 @@ early_idt_handler_common:
|
|
|
|
20:
|
|
decl early_recursion_flag(%rip)
|
|
- jmp restore_regs_and_iret
|
|
+ jmp restore_regs_and_return_to_kernel
|
|
END(early_idt_handler_common)
|
|
|
|
__INITDATA
|
|
--
|
|
2.14.2
|
|
|