]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0088-x86-entry-64-Move-SWAPGS-into-the-common-IRET-to-use.patch
add objtool build fix
[pve-kernel.git] / patches / kernel / 0088-x86-entry-64-Move-SWAPGS-into-the-common-IRET-to-use.patch
1 From 271bc7d0577bef9f344187eb45ba8682eed242f9 Mon Sep 17 00:00:00 2001
2 From: Andy Lutomirski <luto@kernel.org>
3 Date: Thu, 2 Nov 2017 00:59:00 -0700
4 Subject: [PATCH 088/233] x86/entry/64: Move SWAPGS into the common
5 IRET-to-usermode path
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 CVE-2017-5754
11
12 All of the code paths that ended up doing IRET to usermode did
13 SWAPGS immediately beforehand. Move the SWAPGS into the common
14 code.
15
16 Signed-off-by: Andy Lutomirski <luto@kernel.org>
17 Cc: Borislav Petkov <bpetkov@suse.de>
18 Cc: Brian Gerst <brgerst@gmail.com>
19 Cc: Dave Hansen <dave.hansen@intel.com>
20 Cc: Linus Torvalds <torvalds@linux-foundation.org>
21 Cc: Peter Zijlstra <peterz@infradead.org>
22 Cc: Thomas Gleixner <tglx@linutronix.de>
23 Link: http://lkml.kernel.org/r/27fd6f45b7cd640de38fb9066fd0349bcd11f8e1.1509609304.git.luto@kernel.org
24 Signed-off-by: Ingo Molnar <mingo@kernel.org>
25 (cherry picked from commit 8a055d7f411d41755ce30db5bb65b154777c4b78)
26 Signed-off-by: Andy Whitcroft <apw@canonical.com>
27 Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
28 (cherry picked from commit 62a85594f9be3baeb2495089f1c2980bc497d03b)
29 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
30 ---
31 arch/x86/entry/entry_64.S | 32 ++++++++++++++------------------
32 arch/x86/entry/entry_64_compat.S | 3 +--
33 2 files changed, 15 insertions(+), 20 deletions(-)
34
35 diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
36 index e546441fbec3..7c8258e3ad2d 100644
37 --- a/arch/x86/entry/entry_64.S
38 +++ b/arch/x86/entry/entry_64.S
39 @@ -249,12 +249,14 @@ return_from_SYSCALL_64:
40
41 /*
42 * Try to use SYSRET instead of IRET if we're returning to
43 - * a completely clean 64-bit userspace context.
44 + * a completely clean 64-bit userspace context. If we're not,
45 + * go to the slow exit path.
46 */
47 movq RCX(%rsp), %rcx
48 movq RIP(%rsp), %r11
49 - cmpq %rcx, %r11 /* RCX == RIP */
50 - jne opportunistic_sysret_failed
51 +
52 + cmpq %rcx, %r11 /* SYSRET requires RCX == RIP */
53 + jne swapgs_restore_regs_and_return_to_usermode
54
55 /*
56 * On Intel CPUs, SYSRET with non-canonical RCX/RIP will #GP
57 @@ -272,14 +274,14 @@ return_from_SYSCALL_64:
58
59 /* If this changed %rcx, it was not canonical */
60 cmpq %rcx, %r11
61 - jne opportunistic_sysret_failed
62 + jne swapgs_restore_regs_and_return_to_usermode
63
64 cmpq $__USER_CS, CS(%rsp) /* CS must match SYSRET */
65 - jne opportunistic_sysret_failed
66 + jne swapgs_restore_regs_and_return_to_usermode
67
68 movq R11(%rsp), %r11
69 cmpq %r11, EFLAGS(%rsp) /* R11 == RFLAGS */
70 - jne opportunistic_sysret_failed
71 + jne swapgs_restore_regs_and_return_to_usermode
72
73 /*
74 * SYSCALL clears RF when it saves RFLAGS in R11 and SYSRET cannot
75 @@ -300,12 +302,12 @@ return_from_SYSCALL_64:
76 * would never get past 'stuck_here'.
77 */
78 testq $(X86_EFLAGS_RF|X86_EFLAGS_TF), %r11
79 - jnz opportunistic_sysret_failed
80 + jnz swapgs_restore_regs_and_return_to_usermode
81
82 /* nothing to check for RSP */
83
84 cmpq $__USER_DS, SS(%rsp) /* SS must match SYSRET */
85 - jne opportunistic_sysret_failed
86 + jne swapgs_restore_regs_and_return_to_usermode
87
88 /*
89 * We win! This label is here just for ease of understanding
90 @@ -318,10 +320,6 @@ syscall_return_via_sysret:
91 movq RSP(%rsp), %rsp
92 UNWIND_HINT_EMPTY
93 USERGS_SYSRET64
94 -
95 -opportunistic_sysret_failed:
96 - SWAPGS
97 - jmp restore_regs_and_return_to_usermode
98 END(entry_SYSCALL_64)
99
100 ENTRY(stub_ptregs_64)
101 @@ -422,8 +420,7 @@ ENTRY(ret_from_fork)
102 movq %rsp, %rdi
103 call syscall_return_slowpath /* returns with IRQs disabled */
104 TRACE_IRQS_ON /* user mode is traced as IRQS on */
105 - SWAPGS
106 - jmp restore_regs_and_return_to_usermode
107 + jmp swapgs_restore_regs_and_return_to_usermode
108
109 1:
110 /* kernel thread */
111 @@ -611,9 +608,8 @@ GLOBAL(retint_user)
112 mov %rsp,%rdi
113 call prepare_exit_to_usermode
114 TRACE_IRQS_IRETQ
115 - SWAPGS
116
117 -GLOBAL(restore_regs_and_return_to_usermode)
118 +GLOBAL(swapgs_restore_regs_and_return_to_usermode)
119 #ifdef CONFIG_DEBUG_ENTRY
120 /* Assert that pt_regs indicates user mode. */
121 testl $3, CS(%rsp)
122 @@ -621,6 +617,7 @@ GLOBAL(restore_regs_and_return_to_usermode)
123 ud2
124 1:
125 #endif
126 + SWAPGS
127 RESTORE_EXTRA_REGS
128 RESTORE_C_REGS
129 REMOVE_PT_GPREGS_FROM_STACK 8
130 @@ -1355,8 +1352,7 @@ ENTRY(nmi)
131 * Return back to user mode. We must *not* do the normal exit
132 * work, because we don't want to enable interrupts.
133 */
134 - SWAPGS
135 - jmp restore_regs_and_return_to_usermode
136 + jmp swapgs_restore_regs_and_return_to_usermode
137
138 .Lnmi_from_kernel:
139 /*
140 diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
141 index 2b3a88feaa2b..be745b7a3e3e 100644
142 --- a/arch/x86/entry/entry_64_compat.S
143 +++ b/arch/x86/entry/entry_64_compat.S
144 @@ -336,8 +336,7 @@ ENTRY(entry_INT80_compat)
145
146 /* Go back to user mode. */
147 TRACE_IRQS_ON
148 - SWAPGS
149 - jmp restore_regs_and_return_to_usermode
150 + jmp swapgs_restore_regs_and_return_to_usermode
151 END(entry_INT80_compat)
152
153 ALIGN
154 --
155 2.14.2
156