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