0147-x86-entry-Fix-assumptions-that-the-HW-TSS-is-at-the-.patch 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. From 01e4ee94acbd960e302c23481529a5f5323d9969 Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Mon, 4 Dec 2017 15:07:17 +0100
  4. Subject: [PATCH 147/242] x86/entry: Fix assumptions that the HW TSS is at the
  5. beginning of cpu_tss
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. CVE-2017-5754
  10. A future patch will move SYSENTER_stack to the beginning of cpu_tss
  11. to help detect overflow. Before this can happen, fix several code
  12. paths that hardcode assumptions about the old layout.
  13. Signed-off-by: Andy Lutomirski <[email protected]>
  14. Signed-off-by: Thomas Gleixner <[email protected]>
  15. Reviewed-by: Borislav Petkov <[email protected]>
  16. Reviewed-by: Dave Hansen <[email protected]>
  17. Reviewed-by: Thomas Gleixner <[email protected]>
  18. Cc: Boris Ostrovsky <[email protected]>
  19. Cc: Borislav Petkov <[email protected]>
  20. Cc: Borislav Petkov <[email protected]>
  21. Cc: Brian Gerst <[email protected]>
  22. Cc: Dave Hansen <[email protected]>
  23. Cc: David Laight <[email protected]>
  24. Cc: Denys Vlasenko <[email protected]>
  25. Cc: Eduardo Valentin <[email protected]>
  26. Cc: Greg KH <[email protected]>
  27. Cc: H. Peter Anvin <[email protected]>
  28. Cc: Josh Poimboeuf <[email protected]>
  29. Cc: Juergen Gross <[email protected]>
  30. Cc: Linus Torvalds <[email protected]>
  31. Cc: Peter Zijlstra <[email protected]>
  32. Cc: Rik van Riel <[email protected]>
  33. Cc: Will Deacon <[email protected]>
  34. Cc: [email protected]
  35. Cc: [email protected]
  36. Cc: [email protected]
  37. Cc: [email protected]
  38. Link: https://lkml.kernel.org/r/[email protected]
  39. Signed-off-by: Ingo Molnar <[email protected]>
  40. (backported from commit 7fb983b4dd569e08564134a850dfd4eb1c63d9b8)
  41. Signed-off-by: Andy Whitcroft <[email protected]>
  42. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  43. (cherry picked from commit 7123a5de72dc59dea18ce8886e7db726f7259caf)
  44. Signed-off-by: Fabian Grünbichler <[email protected]>
  45. ---
  46. arch/x86/include/asm/desc.h | 2 +-
  47. arch/x86/include/asm/processor.h | 9 +++++++--
  48. arch/x86/kernel/cpu/common.c | 8 ++++----
  49. arch/x86/kernel/doublefault.c | 36 +++++++++++++++++-------------------
  50. arch/x86/kvm/vmx.c | 2 +-
  51. arch/x86/power/cpu.c | 13 +++++++------
  52. 6 files changed, 37 insertions(+), 33 deletions(-)
  53. diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
  54. index 81c9b1e8cae9..b817fe247506 100644
  55. --- a/arch/x86/include/asm/desc.h
  56. +++ b/arch/x86/include/asm/desc.h
  57. @@ -190,7 +190,7 @@ static inline void set_tssldt_descriptor(void *d, unsigned long addr,
  58. #endif
  59. }
  60. -static inline void __set_tss_desc(unsigned cpu, unsigned int entry, void *addr)
  61. +static inline void __set_tss_desc(unsigned cpu, unsigned int entry, struct x86_hw_tss *addr)
  62. {
  63. struct desc_struct *d = get_cpu_gdt_rw(cpu);
  64. tss_desc tss;
  65. diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
  66. index 5225917f9760..78123abdb046 100644
  67. --- a/arch/x86/include/asm/processor.h
  68. +++ b/arch/x86/include/asm/processor.h
  69. @@ -161,7 +161,7 @@ extern struct cpuinfo_x86 new_cpu_data;
  70. #include <linux/thread_info.h>
  71. -extern struct tss_struct doublefault_tss;
  72. +extern struct x86_hw_tss doublefault_tss;
  73. extern __u32 cpu_caps_cleared[NCAPINTS];
  74. extern __u32 cpu_caps_set[NCAPINTS];
  75. @@ -246,6 +246,11 @@ static inline void load_cr3(pgd_t *pgdir)
  76. write_cr3(__pa(pgdir));
  77. }
  78. +/*
  79. + * Note that while the legacy 'TSS' name comes from 'Task State Segment',
  80. + * on modern x86 CPUs the TSS also holds information important to 64-bit mode,
  81. + * unrelated to the task-switch mechanism:
  82. + */
  83. #ifdef CONFIG_X86_32
  84. /* This is the TSS defined by the hardware. */
  85. struct x86_hw_tss {
  86. @@ -316,7 +321,7 @@ struct x86_hw_tss {
  87. #define IO_BITMAP_BITS 65536
  88. #define IO_BITMAP_BYTES (IO_BITMAP_BITS/8)
  89. #define IO_BITMAP_LONGS (IO_BITMAP_BYTES/sizeof(long))
  90. -#define IO_BITMAP_OFFSET offsetof(struct tss_struct, io_bitmap)
  91. +#define IO_BITMAP_OFFSET (offsetof(struct tss_struct, io_bitmap) - offsetof(struct tss_struct, x86_tss))
  92. #define INVALID_IO_BITMAP_OFFSET 0x8000
  93. struct tss_struct {
  94. diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
  95. index ffee73ec1af1..e526d82b546c 100644
  96. --- a/arch/x86/kernel/cpu/common.c
  97. +++ b/arch/x86/kernel/cpu/common.c
  98. @@ -1558,7 +1558,7 @@ void cpu_init(void)
  99. }
  100. }
  101. - t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
  102. + t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
  103. /*
  104. * <= is required because the CPU will access up to
  105. @@ -1576,7 +1576,7 @@ void cpu_init(void)
  106. * Initialize the TSS. Don't bother initializing sp0, as the initial
  107. * task never enters user mode.
  108. */
  109. - set_tss_desc(cpu, t);
  110. + set_tss_desc(cpu, &t->x86_tss);
  111. load_TR_desc();
  112. load_mm_ldt(&init_mm);
  113. @@ -1633,12 +1633,12 @@ void cpu_init(void)
  114. * Initialize the TSS. Don't bother initializing sp0, as the initial
  115. * task never enters user mode.
  116. */
  117. - set_tss_desc(cpu, t);
  118. + set_tss_desc(cpu, &t->x86_tss);
  119. load_TR_desc();
  120. load_mm_ldt(&init_mm);
  121. - t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
  122. + t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
  123. #ifdef CONFIG_DOUBLEFAULT
  124. /* Set up doublefault TSS pointer in the GDT */
  125. diff --git a/arch/x86/kernel/doublefault.c b/arch/x86/kernel/doublefault.c
  126. index f9c324e08d85..a9fe79d49d39 100644
  127. --- a/arch/x86/kernel/doublefault.c
  128. +++ b/arch/x86/kernel/doublefault.c
  129. @@ -49,25 +49,23 @@ static void doublefault_fn(void)
  130. cpu_relax();
  131. }
  132. -struct tss_struct doublefault_tss __cacheline_aligned = {
  133. - .x86_tss = {
  134. - .sp0 = STACK_START,
  135. - .ss0 = __KERNEL_DS,
  136. - .ldt = 0,
  137. - .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
  138. -
  139. - .ip = (unsigned long) doublefault_fn,
  140. - /* 0x2 bit is always set */
  141. - .flags = X86_EFLAGS_SF | 0x2,
  142. - .sp = STACK_START,
  143. - .es = __USER_DS,
  144. - .cs = __KERNEL_CS,
  145. - .ss = __KERNEL_DS,
  146. - .ds = __USER_DS,
  147. - .fs = __KERNEL_PERCPU,
  148. -
  149. - .__cr3 = __pa_nodebug(swapper_pg_dir),
  150. - }
  151. +struct x86_hw_tss doublefault_tss __cacheline_aligned = {
  152. + .sp0 = STACK_START,
  153. + .ss0 = __KERNEL_DS,
  154. + .ldt = 0,
  155. + .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,
  156. +
  157. + .ip = (unsigned long) doublefault_fn,
  158. + /* 0x2 bit is always set */
  159. + .flags = X86_EFLAGS_SF | 0x2,
  160. + .sp = STACK_START,
  161. + .es = __USER_DS,
  162. + .cs = __KERNEL_CS,
  163. + .ss = __KERNEL_DS,
  164. + .ds = __USER_DS,
  165. + .fs = __KERNEL_PERCPU,
  166. +
  167. + .__cr3 = __pa_nodebug(swapper_pg_dir),
  168. };
  169. /* dummy for do_double_fault() call */
  170. diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
  171. index dd4996a96c71..a7c5a47beab7 100644
  172. --- a/arch/x86/kvm/vmx.c
  173. +++ b/arch/x86/kvm/vmx.c
  174. @@ -2280,7 +2280,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
  175. * processors. See 22.2.4.
  176. */
  177. vmcs_writel(HOST_TR_BASE,
  178. - (unsigned long)this_cpu_ptr(&cpu_tss));
  179. + (unsigned long)this_cpu_ptr(&cpu_tss.x86_tss));
  180. vmcs_writel(HOST_GDTR_BASE, (unsigned long)gdt); /* 22.2.4 */
  181. /*
  182. diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
  183. index 78459a6d455a..48cd87fc7222 100644
  184. --- a/arch/x86/power/cpu.c
  185. +++ b/arch/x86/power/cpu.c
  186. @@ -165,12 +165,13 @@ static void fix_processor_context(void)
  187. struct desc_struct *desc = get_cpu_gdt_rw(cpu);
  188. tss_desc tss;
  189. #endif
  190. - set_tss_desc(cpu, t); /*
  191. - * This just modifies memory; should not be
  192. - * necessary. But... This is necessary, because
  193. - * 386 hardware has concept of busy TSS or some
  194. - * similar stupidity.
  195. - */
  196. +
  197. + /*
  198. + * This just modifies memory; should not be necessary. But... This is
  199. + * necessary, because 386 hardware has concept of busy TSS or some
  200. + * similar stupidity.
  201. + */
  202. + set_tss_desc(cpu, &t->x86_tss);
  203. #ifdef CONFIG_X86_64
  204. memcpy(&tss, &desc[GDT_ENTRY_TSS], sizeof(tss_desc));
  205. --
  206. 2.14.2