]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0190-x86-mm-pti-Add-infrastructure-for-page-table-isolati.patch
KPTI: add follow-up fixes
[pve-kernel.git] / patches / kernel / 0190-x86-mm-pti-Add-infrastructure-for-page-table-isolati.patch
1 From 384e4cfab1886f8abb94fe16abbad2a034612f78 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Mon, 4 Dec 2017 15:07:36 +0100
4 Subject: [PATCH 190/241] x86/mm/pti: Add infrastructure for page table
5 isolation
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 Add the initial files for kernel page table isolation, with a minimal init
13 function and the boot time detection for this misfeature.
14
15 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
16 Reviewed-by: Borislav Petkov <bp@suse.de>
17 Cc: Andy Lutomirski <luto@kernel.org>
18 Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
19 Cc: Borislav Petkov <bp@alien8.de>
20 Cc: Brian Gerst <brgerst@gmail.com>
21 Cc: Dave Hansen <dave.hansen@linux.intel.com>
22 Cc: David Laight <David.Laight@aculab.com>
23 Cc: Denys Vlasenko <dvlasenk@redhat.com>
24 Cc: Eduardo Valentin <eduval@amazon.com>
25 Cc: Greg KH <gregkh@linuxfoundation.org>
26 Cc: H. Peter Anvin <hpa@zytor.com>
27 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
28 Cc: Juergen Gross <jgross@suse.com>
29 Cc: Linus Torvalds <torvalds@linux-foundation.org>
30 Cc: Peter Zijlstra <peterz@infradead.org>
31 Cc: Will Deacon <will.deacon@arm.com>
32 Cc: aliguori@amazon.com
33 Cc: daniel.gruss@iaik.tugraz.at
34 Cc: hughd@google.com
35 Cc: keescook@google.com
36 Signed-off-by: Ingo Molnar <mingo@kernel.org>
37 (backported from commit aa8c6248f8c75acfd610fe15d8cae23cf70d9d09)
38 Signed-off-by: Andy Whitcroft <apw@canonical.com>
39 Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
40 (cherry picked from commit 50da124a01ed7a59f9b2c9551f622c5a27d1caec)
41 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
42 ---
43 Documentation/admin-guide/kernel-parameters.txt | 2 +
44 arch/x86/mm/Makefile | 7 ++-
45 arch/x86/entry/calling.h | 7 +++
46 arch/x86/include/asm/pti.h | 14 +++++
47 include/linux/pti.h | 11 ++++
48 arch/x86/boot/compressed/pagetable.c | 3 +
49 arch/x86/mm/init.c | 2 +
50 arch/x86/mm/pti.c | 84 +++++++++++++++++++++++++
51 init/main.c | 3 +
52 9 files changed, 130 insertions(+), 3 deletions(-)
53 create mode 100644 arch/x86/include/asm/pti.h
54 create mode 100644 include/linux/pti.h
55 create mode 100644 arch/x86/mm/pti.c
56
57 diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
58 index 3510e255ef4c..e2a4608da5d2 100644
59 --- a/Documentation/admin-guide/kernel-parameters.txt
60 +++ b/Documentation/admin-guide/kernel-parameters.txt
61 @@ -2677,6 +2677,8 @@
62 steal time is computed, but won't influence scheduler
63 behaviour
64
65 + nopti [X86-64] Disable kernel page table isolation
66 +
67 nolapic [X86-32,APIC] Do not enable or use the local APIC.
68
69 nolapic_timer [X86-32,APIC] Do not use the local APIC timer.
70 diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile
71 index 76f5399a8356..7aa68fc18abe 100644
72 --- a/arch/x86/mm/Makefile
73 +++ b/arch/x86/mm/Makefile
74 @@ -35,7 +35,8 @@ obj-$(CONFIG_AMD_NUMA) += amdtopology.o
75 obj-$(CONFIG_ACPI_NUMA) += srat.o
76 obj-$(CONFIG_NUMA_EMU) += numa_emulation.o
77
78 -obj-$(CONFIG_X86_INTEL_MPX) += mpx.o
79 -obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
80 -obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
81 +obj-$(CONFIG_X86_INTEL_MPX) += mpx.o
82 +obj-$(CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS) += pkeys.o
83 +obj-$(CONFIG_RANDOMIZE_MEMORY) += kaslr.o
84 +obj-$(CONFIG_PAGE_TABLE_ISOLATION) += pti.o
85
86 diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
87 index dde6262be0a3..bb56f5346ae8 100644
88 --- a/arch/x86/entry/calling.h
89 +++ b/arch/x86/entry/calling.h
90 @@ -204,18 +204,23 @@ For 32-bit we have the following conventions - kernel is built with
91 .endm
92
93 .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
94 + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
95 mov %cr3, \scratch_reg
96 ADJUST_KERNEL_CR3 \scratch_reg
97 mov \scratch_reg, %cr3
98 +.Lend_\@:
99 .endm
100
101 .macro SWITCH_TO_USER_CR3 scratch_reg:req
102 + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
103 mov %cr3, \scratch_reg
104 ADJUST_USER_CR3 \scratch_reg
105 mov \scratch_reg, %cr3
106 +.Lend_\@:
107 .endm
108
109 .macro SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg:req save_reg:req
110 + ALTERNATIVE "jmp .Ldone_\@", "", X86_FEATURE_PTI
111 movq %cr3, \scratch_reg
112 movq \scratch_reg, \save_reg
113 /*
114 @@ -232,11 +237,13 @@ For 32-bit we have the following conventions - kernel is built with
115 .endm
116
117 .macro RESTORE_CR3 save_reg:req
118 + ALTERNATIVE "jmp .Lend_\@", "", X86_FEATURE_PTI
119 /*
120 * The CR3 write could be avoided when not changing its value,
121 * but would require a CR3 read *and* a scratch register.
122 */
123 movq \save_reg, %cr3
124 +.Lend_\@:
125 .endm
126
127 #else /* CONFIG_PAGE_TABLE_ISOLATION=n: */
128 diff --git a/arch/x86/include/asm/pti.h b/arch/x86/include/asm/pti.h
129 new file mode 100644
130 index 000000000000..0b5ef05b2d2d
131 --- /dev/null
132 +++ b/arch/x86/include/asm/pti.h
133 @@ -0,0 +1,14 @@
134 +// SPDX-License-Identifier: GPL-2.0
135 +#ifndef _ASM_X86_PTI_H
136 +#define _ASM_X86_PTI_H
137 +#ifndef __ASSEMBLY__
138 +
139 +#ifdef CONFIG_PAGE_TABLE_ISOLATION
140 +extern void pti_init(void);
141 +extern void pti_check_boottime_disable(void);
142 +#else
143 +static inline void pti_check_boottime_disable(void) { }
144 +#endif
145 +
146 +#endif /* __ASSEMBLY__ */
147 +#endif /* _ASM_X86_PTI_H */
148 diff --git a/include/linux/pti.h b/include/linux/pti.h
149 new file mode 100644
150 index 000000000000..0174883a935a
151 --- /dev/null
152 +++ b/include/linux/pti.h
153 @@ -0,0 +1,11 @@
154 +// SPDX-License-Identifier: GPL-2.0
155 +#ifndef _INCLUDE_PTI_H
156 +#define _INCLUDE_PTI_H
157 +
158 +#ifdef CONFIG_PAGE_TABLE_ISOLATION
159 +#include <asm/pti.h>
160 +#else
161 +static inline void pti_init(void) { }
162 +#endif
163 +
164 +#endif
165 diff --git a/arch/x86/boot/compressed/pagetable.c b/arch/x86/boot/compressed/pagetable.c
166 index 28029be47fbb..21d8839cdaa7 100644
167 --- a/arch/x86/boot/compressed/pagetable.c
168 +++ b/arch/x86/boot/compressed/pagetable.c
169 @@ -15,6 +15,9 @@
170 #define __pa(x) ((unsigned long)(x))
171 #define __va(x) ((void *)((unsigned long)(x)))
172
173 +/* No PAGE_TABLE_ISOLATION support needed either: */
174 +#undef CONFIG_PAGE_TABLE_ISOLATION
175 +
176 #include "misc.h"
177
178 /* These actually do the work of building the kernel identity maps. */
179 diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
180 index 020223420308..af75069fb116 100644
181 --- a/arch/x86/mm/init.c
182 +++ b/arch/x86/mm/init.c
183 @@ -20,6 +20,7 @@
184 #include <asm/kaslr.h>
185 #include <asm/hypervisor.h>
186 #include <asm/cpufeature.h>
187 +#include <asm/pti.h>
188
189 /*
190 * We need to define the tracepoints somewhere, and tlb.c
191 @@ -630,6 +631,7 @@ void __init init_mem_mapping(void)
192 {
193 unsigned long end;
194
195 + pti_check_boottime_disable();
196 probe_page_size_mask();
197 setup_pcid();
198
199 diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
200 new file mode 100644
201 index 000000000000..375f23a758bc
202 --- /dev/null
203 +++ b/arch/x86/mm/pti.c
204 @@ -0,0 +1,84 @@
205 +/*
206 + * Copyright(c) 2017 Intel Corporation. All rights reserved.
207 + *
208 + * This program is free software; you can redistribute it and/or modify
209 + * it under the terms of version 2 of the GNU General Public License as
210 + * published by the Free Software Foundation.
211 + *
212 + * This program is distributed in the hope that it will be useful, but
213 + * WITHOUT ANY WARRANTY; without even the implied warranty of
214 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
215 + * General Public License for more details.
216 + *
217 + * This code is based in part on work published here:
218 + *
219 + * https://github.com/IAIK/KAISER
220 + *
221 + * The original work was written by and and signed off by for the Linux
222 + * kernel by:
223 + *
224 + * Signed-off-by: Richard Fellner <richard.fellner@student.tugraz.at>
225 + * Signed-off-by: Moritz Lipp <moritz.lipp@iaik.tugraz.at>
226 + * Signed-off-by: Daniel Gruss <daniel.gruss@iaik.tugraz.at>
227 + * Signed-off-by: Michael Schwarz <michael.schwarz@iaik.tugraz.at>
228 + *
229 + * Major changes to the original code by: Dave Hansen <dave.hansen@intel.com>
230 + * Mostly rewritten by Thomas Gleixner <tglx@linutronix.de> and
231 + * Andy Lutomirsky <luto@amacapital.net>
232 + */
233 +#include <linux/kernel.h>
234 +#include <linux/errno.h>
235 +#include <linux/string.h>
236 +#include <linux/types.h>
237 +#include <linux/bug.h>
238 +#include <linux/init.h>
239 +#include <linux/spinlock.h>
240 +#include <linux/mm.h>
241 +#include <linux/uaccess.h>
242 +
243 +#include <asm/cpufeature.h>
244 +#include <asm/hypervisor.h>
245 +#include <asm/cmdline.h>
246 +#include <asm/pti.h>
247 +#include <asm/pgtable.h>
248 +#include <asm/pgalloc.h>
249 +#include <asm/tlbflush.h>
250 +#include <asm/desc.h>
251 +
252 +#undef pr_fmt
253 +#define pr_fmt(fmt) "Kernel/User page tables isolation: " fmt
254 +
255 +static void __init pti_print_if_insecure(const char *reason)
256 +{
257 + if (boot_cpu_has_bug(X86_BUG_CPU_INSECURE))
258 + pr_info("%s\n", reason);
259 +}
260 +
261 +void __init pti_check_boottime_disable(void)
262 +{
263 + if (hypervisor_is_type(X86_HYPER_XEN_PV)) {
264 + pti_print_if_insecure("disabled on XEN PV.");
265 + return;
266 + }
267 +
268 + if (cmdline_find_option_bool(boot_command_line, "nopti")) {
269 + pti_print_if_insecure("disabled on command line.");
270 + return;
271 + }
272 +
273 + if (!boot_cpu_has_bug(X86_BUG_CPU_INSECURE))
274 + return;
275 +
276 + setup_force_cpu_cap(X86_FEATURE_PTI);
277 +}
278 +
279 +/*
280 + * Initialize kernel page table isolation
281 + */
282 +void __init pti_init(void)
283 +{
284 + if (!static_cpu_has(X86_FEATURE_PTI))
285 + return;
286 +
287 + pr_info("enabled\n");
288 +}
289 diff --git a/init/main.c b/init/main.c
290 index de1c495da782..bb0896c24c08 100644
291 --- a/init/main.c
292 +++ b/init/main.c
293 @@ -75,6 +75,7 @@
294 #include <linux/slab.h>
295 #include <linux/perf_event.h>
296 #include <linux/ptrace.h>
297 +#include <linux/pti.h>
298 #include <linux/blkdev.h>
299 #include <linux/elevator.h>
300 #include <linux/sched_clock.h>
301 @@ -506,6 +507,8 @@ static void __init mm_init(void)
302 ioremap_huge_init();
303 /* Should be run before the first non-init thread is created */
304 init_espfix_bsp();
305 + /* Should be run after espfix64 is set up. */
306 + pti_init();
307 }
308
309 asmlinkage __visible void __init start_kernel(void)
310 --
311 2.14.2
312