0190-x86-mm-pti-Add-infrastructure-for-page-table-isolati.patch 9.7 KB

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