0142-x86-entry-64-Allocate-and-enable-the-SYSENTER-stack.patch 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. From c8756c2077aba1a33ec603766211fdb1dad34577 Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Mon, 4 Dec 2017 15:07:12 +0100
  4. Subject: [PATCH 142/242] x86/entry/64: Allocate and enable the SYSENTER stack
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. CVE-2017-5754
  9. This will simplify future changes that want scratch variables early in
  10. the SYSENTER handler -- they'll be able to spill registers to the
  11. stack. It also lets us get rid of a SWAPGS_UNSAFE_STACK user.
  12. This does not depend on CONFIG_IA32_EMULATION=y because we'll want the
  13. stack space even without IA32 emulation.
  14. As far as I can tell, the reason that this wasn't done from day 1 is
  15. that we use IST for #DB and #BP, which is IMO rather nasty and causes
  16. a lot more problems than it solves. But, since #DB uses IST, we don't
  17. actually need a real stack for SYSENTER (because SYSENTER with TF set
  18. will invoke #DB on the IST stack rather than the SYSENTER stack).
  19. I want to remove IST usage from these vectors some day, and this patch
  20. is a prerequisite for that as well.
  21. Signed-off-by: Andy Lutomirski <[email protected]>
  22. Signed-off-by: Thomas Gleixner <[email protected]>
  23. Reviewed-by: Thomas Gleixner <[email protected]>
  24. Reviewed-by: Borislav Petkov <[email protected]>
  25. Cc: Boris Ostrovsky <[email protected]>
  26. Cc: Borislav Petkov <[email protected]>
  27. Cc: Borislav Petkov <[email protected]>
  28. Cc: Brian Gerst <[email protected]>
  29. Cc: Dave Hansen <[email protected]>
  30. Cc: Dave Hansen <[email protected]>
  31. Cc: David Laight <[email protected]>
  32. Cc: Denys Vlasenko <[email protected]>
  33. Cc: Eduardo Valentin <[email protected]>
  34. Cc: Greg KH <[email protected]>
  35. Cc: H. Peter Anvin <[email protected]>
  36. Cc: Josh Poimboeuf <[email protected]>
  37. Cc: Juergen Gross <[email protected]>
  38. Cc: Linus Torvalds <[email protected]>
  39. Cc: Peter Zijlstra <[email protected]>
  40. Cc: Rik van Riel <[email protected]>
  41. Cc: Will Deacon <[email protected]>
  42. Cc: [email protected]
  43. Cc: [email protected]
  44. Cc: [email protected]
  45. Cc: [email protected]
  46. Link: https://lkml.kernel.org/r/[email protected]
  47. Signed-off-by: Ingo Molnar <[email protected]>
  48. (cherry picked from commit 1a79797b58cddfa948420a7553241c79c013e3ca)
  49. Signed-off-by: Andy Whitcroft <[email protected]>
  50. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  51. (cherry picked from commit 8e621515fa8d1649b031f34b9d498dcd865db1c3)
  52. Signed-off-by: Fabian Grünbichler <[email protected]>
  53. ---
  54. arch/x86/include/asm/processor.h | 3 ---
  55. arch/x86/kernel/asm-offsets.c | 5 +++++
  56. arch/x86/kernel/asm-offsets_32.c | 5 -----
  57. arch/x86/kernel/cpu/common.c | 4 +++-
  58. arch/x86/kernel/process.c | 2 --
  59. arch/x86/kernel/traps.c | 3 +--
  60. arch/x86/entry/entry_64_compat.S | 2 +-
  61. 7 files changed, 10 insertions(+), 14 deletions(-)
  62. diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
  63. index 79739e5f939a..5225917f9760 100644
  64. --- a/arch/x86/include/asm/processor.h
  65. +++ b/arch/x86/include/asm/processor.h
  66. @@ -333,14 +333,11 @@ struct tss_struct {
  67. */
  68. unsigned long io_bitmap[IO_BITMAP_LONGS + 1];
  69. -#ifdef CONFIG_X86_32
  70. /*
  71. * Space for the temporary SYSENTER stack.
  72. */
  73. unsigned long SYSENTER_stack_canary;
  74. unsigned long SYSENTER_stack[64];
  75. -#endif
  76. -
  77. } ____cacheline_aligned;
  78. DECLARE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss);
  79. diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
  80. index de827d6ac8c2..031bd35bd911 100644
  81. --- a/arch/x86/kernel/asm-offsets.c
  82. +++ b/arch/x86/kernel/asm-offsets.c
  83. @@ -92,4 +92,9 @@ void common(void) {
  84. BLANK();
  85. DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
  86. +
  87. + /* Offset from cpu_tss to SYSENTER_stack */
  88. + OFFSET(CPU_TSS_SYSENTER_stack, tss_struct, SYSENTER_stack);
  89. + /* Size of SYSENTER_stack */
  90. + DEFINE(SIZEOF_SYSENTER_stack, sizeof(((struct tss_struct *)0)->SYSENTER_stack));
  91. }
  92. diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
  93. index 880aa093268d..d09b161a3bd0 100644
  94. --- a/arch/x86/kernel/asm-offsets_32.c
  95. +++ b/arch/x86/kernel/asm-offsets_32.c
  96. @@ -52,11 +52,6 @@ void foo(void)
  97. DEFINE(TSS_sysenter_sp0, offsetof(struct tss_struct, x86_tss.sp0) -
  98. offsetofend(struct tss_struct, SYSENTER_stack));
  99. - /* Offset from cpu_tss to SYSENTER_stack */
  100. - OFFSET(CPU_TSS_SYSENTER_stack, tss_struct, SYSENTER_stack);
  101. - /* Size of SYSENTER_stack */
  102. - DEFINE(SIZEOF_SYSENTER_stack, sizeof(((struct tss_struct *)0)->SYSENTER_stack));
  103. -
  104. #ifdef CONFIG_CC_STACKPROTECTOR
  105. BLANK();
  106. OFFSET(stack_canary_offset, stack_canary, canary);
  107. diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
  108. index 121fe3570d6f..aa97e4cd3a33 100644
  109. --- a/arch/x86/kernel/cpu/common.c
  110. +++ b/arch/x86/kernel/cpu/common.c
  111. @@ -1362,7 +1362,9 @@ void syscall_init(void)
  112. * AMD doesn't allow SYSENTER in long mode (either 32- or 64-bit).
  113. */
  114. wrmsrl_safe(MSR_IA32_SYSENTER_CS, (u64)__KERNEL_CS);
  115. - wrmsrl_safe(MSR_IA32_SYSENTER_ESP, 0ULL);
  116. + wrmsrl_safe(MSR_IA32_SYSENTER_ESP,
  117. + (unsigned long)this_cpu_ptr(&cpu_tss) +
  118. + offsetofend(struct tss_struct, SYSENTER_stack));
  119. wrmsrl_safe(MSR_IA32_SYSENTER_EIP, (u64)entry_SYSENTER_compat);
  120. #else
  121. wrmsrl(MSR_CSTAR, (unsigned long)ignore_sysret);
  122. diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
  123. index ccf3a4f4ef68..aa86e810fb54 100644
  124. --- a/arch/x86/kernel/process.c
  125. +++ b/arch/x86/kernel/process.c
  126. @@ -70,9 +70,7 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
  127. */
  128. .io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 },
  129. #endif
  130. -#ifdef CONFIG_X86_32
  131. .SYSENTER_stack_canary = STACK_END_MAGIC,
  132. -#endif
  133. };
  134. EXPORT_PER_CPU_SYMBOL(cpu_tss);
  135. diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
  136. index 3a46cab2696e..7b1d0df624cf 100644
  137. --- a/arch/x86/kernel/traps.c
  138. +++ b/arch/x86/kernel/traps.c
  139. @@ -806,14 +806,13 @@ dotraplinkage void do_debug(struct pt_regs *regs, long error_code)
  140. debug_stack_usage_dec();
  141. exit:
  142. -#if defined(CONFIG_X86_32)
  143. /*
  144. * This is the most likely code path that involves non-trivial use
  145. * of the SYSENTER stack. Check that we haven't overrun it.
  146. */
  147. WARN(this_cpu_read(cpu_tss.SYSENTER_stack_canary) != STACK_END_MAGIC,
  148. "Overran or corrupted SYSENTER stack\n");
  149. -#endif
  150. +
  151. ist_exit(regs);
  152. }
  153. NOKPROBE_SYMBOL(do_debug);
  154. diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
  155. index be745b7a3e3e..1f76b66518ee 100644
  156. --- a/arch/x86/entry/entry_64_compat.S
  157. +++ b/arch/x86/entry/entry_64_compat.S
  158. @@ -47,7 +47,7 @@
  159. */
  160. ENTRY(entry_SYSENTER_compat)
  161. /* Interrupts are off on entry. */
  162. - SWAPGS_UNSAFE_STACK
  163. + SWAPGS
  164. movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
  165. /*
  166. --
  167. 2.14.2