]>
Commit | Line | Data |
---|---|---|
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | |
2 | From: Andy Lutomirski <luto@kernel.org> | |
3 | Date: Thu, 2 Nov 2017 00:58:59 -0700 | |
4 | Subject: [PATCH] x86/entry/64: Split the IRET-to-user and IRET-to-kernel paths | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | CVE-2017-5754 | |
10 | ||
11 | These code paths will diverge soon. | |
12 | ||
13 | Signed-off-by: Andy Lutomirski <luto@kernel.org> | |
14 | Cc: Borislav Petkov <bpetkov@suse.de> | |
15 | Cc: Brian Gerst <brgerst@gmail.com> | |
16 | Cc: Dave Hansen <dave.hansen@intel.com> | |
17 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
18 | Cc: Peter Zijlstra <peterz@infradead.org> | |
19 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
20 | Link: http://lkml.kernel.org/r/dccf8c7b3750199b4b30383c812d4e2931811509.1509609304.git.luto@kernel.org | |
21 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
22 | (cherry picked from commit 26c4ef9c49d8a0341f6d97ce2cfdd55d1236ed29) | |
23 | Signed-off-by: Andy Whitcroft <apw@canonical.com> | |
24 | Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> | |
25 | (cherry picked from commit 64adfba0aeb668304d171c383ac80b22158ec128) | |
26 | Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com> | |
27 | --- | |
28 | arch/x86/entry/entry_64.S | 34 +++++++++++++++++++++++++--------- | |
29 | arch/x86/entry/entry_64_compat.S | 2 +- | |
30 | arch/x86/kernel/head_64.S | 2 +- | |
31 | 3 files changed, 27 insertions(+), 11 deletions(-) | |
32 | ||
33 | diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S | |
34 | index fac354ddf056..e546441fbec3 100644 | |
35 | --- a/arch/x86/entry/entry_64.S | |
36 | +++ b/arch/x86/entry/entry_64.S | |
37 | @@ -321,7 +321,7 @@ syscall_return_via_sysret: | |
38 | ||
39 | opportunistic_sysret_failed: | |
40 | SWAPGS | |
41 | - jmp restore_regs_and_iret | |
42 | + jmp restore_regs_and_return_to_usermode | |
43 | END(entry_SYSCALL_64) | |
44 | ||
45 | ENTRY(stub_ptregs_64) | |
46 | @@ -423,7 +423,7 @@ ENTRY(ret_from_fork) | |
47 | call syscall_return_slowpath /* returns with IRQs disabled */ | |
48 | TRACE_IRQS_ON /* user mode is traced as IRQS on */ | |
49 | SWAPGS | |
50 | - jmp restore_regs_and_iret | |
51 | + jmp restore_regs_and_return_to_usermode | |
52 | ||
53 | 1: | |
54 | /* kernel thread */ | |
55 | @@ -612,7 +612,20 @@ GLOBAL(retint_user) | |
56 | call prepare_exit_to_usermode | |
57 | TRACE_IRQS_IRETQ | |
58 | SWAPGS | |
59 | - jmp restore_regs_and_iret | |
60 | + | |
61 | +GLOBAL(restore_regs_and_return_to_usermode) | |
62 | +#ifdef CONFIG_DEBUG_ENTRY | |
63 | + /* Assert that pt_regs indicates user mode. */ | |
64 | + testl $3, CS(%rsp) | |
65 | + jnz 1f | |
66 | + ud2 | |
67 | +1: | |
68 | +#endif | |
69 | + RESTORE_EXTRA_REGS | |
70 | + RESTORE_C_REGS | |
71 | + REMOVE_PT_GPREGS_FROM_STACK 8 | |
72 | + INTERRUPT_RETURN | |
73 | + | |
74 | ||
75 | /* Returning to kernel space */ | |
76 | retint_kernel: | |
77 | @@ -632,11 +645,14 @@ retint_kernel: | |
78 | */ | |
79 | TRACE_IRQS_IRETQ | |
80 | ||
81 | -/* | |
82 | - * At this label, code paths which return to kernel and to user, | |
83 | - * which come from interrupts/exception and from syscalls, merge. | |
84 | - */ | |
85 | -GLOBAL(restore_regs_and_iret) | |
86 | +GLOBAL(restore_regs_and_return_to_kernel) | |
87 | +#ifdef CONFIG_DEBUG_ENTRY | |
88 | + /* Assert that pt_regs indicates kernel mode. */ | |
89 | + testl $3, CS(%rsp) | |
90 | + jz 1f | |
91 | + ud2 | |
92 | +1: | |
93 | +#endif | |
94 | RESTORE_EXTRA_REGS | |
95 | RESTORE_C_REGS | |
96 | REMOVE_PT_GPREGS_FROM_STACK 8 | |
97 | @@ -1340,7 +1356,7 @@ ENTRY(nmi) | |
98 | * work, because we don't want to enable interrupts. | |
99 | */ | |
100 | SWAPGS | |
101 | - jmp restore_regs_and_iret | |
102 | + jmp restore_regs_and_return_to_usermode | |
103 | ||
104 | .Lnmi_from_kernel: | |
105 | /* | |
106 | diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S | |
107 | index d8468ba24be0..2b3a88feaa2b 100644 | |
108 | --- a/arch/x86/entry/entry_64_compat.S | |
109 | +++ b/arch/x86/entry/entry_64_compat.S | |
110 | @@ -337,7 +337,7 @@ ENTRY(entry_INT80_compat) | |
111 | /* Go back to user mode. */ | |
112 | TRACE_IRQS_ON | |
113 | SWAPGS | |
114 | - jmp restore_regs_and_iret | |
115 | + jmp restore_regs_and_return_to_usermode | |
116 | END(entry_INT80_compat) | |
117 | ||
118 | ALIGN | |
119 | diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S | |
120 | index 4117c1e0b3d2..e785734980ad 100644 | |
121 | --- a/arch/x86/kernel/head_64.S | |
122 | +++ b/arch/x86/kernel/head_64.S | |
123 | @@ -311,7 +311,7 @@ early_idt_handler_common: | |
124 | ||
125 | 20: | |
126 | decl early_recursion_flag(%rip) | |
127 | - jmp restore_regs_and_iret | |
128 | + jmp restore_regs_and_return_to_kernel | |
129 | END(early_idt_handler_common) | |
130 | ||
131 | __INITDATA | |
132 | -- | |
133 | 2.14.2 | |
134 |