0101-x86-entry-64-Stop-initializing-TSS.sp0-at-boot.patch 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. From d9170f22073657aceba14c49e8df535df4409a6c Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Thu, 2 Nov 2017 00:59:13 -0700
  4. Subject: [PATCH 101/242] x86/entry/64: Stop initializing TSS.sp0 at boot
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. CVE-2017-5754
  9. In my quest to get rid of thread_struct::sp0, I want to clean up or
  10. remove all of its readers. Two of them are in cpu_init() (32-bit and
  11. 64-bit), and they aren't needed. This is because we never enter
  12. userspace at all on the threads that CPUs are initialized in.
  13. Poison the initial TSS.sp0 and stop initializing it on CPU init.
  14. The comment text mostly comes from Dave Hansen. Thanks!
  15. Signed-off-by: Andy Lutomirski <[email protected]>
  16. Cc: Borislav Petkov <[email protected]>
  17. Cc: Brian Gerst <[email protected]>
  18. Cc: Dave Hansen <[email protected]>
  19. Cc: Linus Torvalds <[email protected]>
  20. Cc: Peter Zijlstra <[email protected]>
  21. Cc: Thomas Gleixner <[email protected]>
  22. Link: http://lkml.kernel.org/r/ee4a00540ad28c6cff475fbcc7769a4460acc861.1509609304.git.luto@kernel.org
  23. Signed-off-by: Ingo Molnar <[email protected]>
  24. (cherry picked from commit 20bb83443ea79087b5e5f8dab4e9d80bb9bf7acb)
  25. Signed-off-by: Andy Whitcroft <[email protected]>
  26. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  27. (cherry picked from commit 8c6b12e88bd87433087ea1f1cd5a9a4975e4623c)
  28. Signed-off-by: Fabian Grünbichler <[email protected]>
  29. ---
  30. arch/x86/kernel/cpu/common.c | 13 ++++++++++---
  31. arch/x86/kernel/process.c | 8 +++++++-
  32. 2 files changed, 17 insertions(+), 4 deletions(-)
  33. diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
  34. index 6562acbfc4e0..121fe3570d6f 100644
  35. --- a/arch/x86/kernel/cpu/common.c
  36. +++ b/arch/x86/kernel/cpu/common.c
  37. @@ -1570,9 +1570,13 @@ void cpu_init(void)
  38. BUG_ON(me->mm);
  39. enter_lazy_tlb(&init_mm, me);
  40. - load_sp0(current->thread.sp0);
  41. + /*
  42. + * Initialize the TSS. Don't bother initializing sp0, as the initial
  43. + * task never enters user mode.
  44. + */
  45. set_tss_desc(cpu, t);
  46. load_TR_desc();
  47. +
  48. load_mm_ldt(&init_mm);
  49. clear_all_debug_regs();
  50. @@ -1594,7 +1598,6 @@ void cpu_init(void)
  51. int cpu = smp_processor_id();
  52. struct task_struct *curr = current;
  53. struct tss_struct *t = &per_cpu(cpu_tss, cpu);
  54. - struct thread_struct *thread = &curr->thread;
  55. wait_for_master_cpu(cpu);
  56. @@ -1624,9 +1627,13 @@ void cpu_init(void)
  57. BUG_ON(curr->mm);
  58. enter_lazy_tlb(&init_mm, curr);
  59. - load_sp0(thread->sp0);
  60. + /*
  61. + * Initialize the TSS. Don't bother initializing sp0, as the initial
  62. + * task never enters user mode.
  63. + */
  64. set_tss_desc(cpu, t);
  65. load_TR_desc();
  66. +
  67. load_mm_ldt(&init_mm);
  68. t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
  69. diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
  70. index 3ca198080ea9..ccf3a4f4ef68 100644
  71. --- a/arch/x86/kernel/process.c
  72. +++ b/arch/x86/kernel/process.c
  73. @@ -48,7 +48,13 @@
  74. */
  75. __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
  76. .x86_tss = {
  77. - .sp0 = TOP_OF_INIT_STACK,
  78. + /*
  79. + * .sp0 is only used when entering ring 0 from a lower
  80. + * privilege level. Since the init task never runs anything
  81. + * but ring 0 code, there is no need for a valid value here.
  82. + * Poison it.
  83. + */
  84. + .sp0 = (1UL << (BITS_PER_LONG-1)) + 1,
  85. #ifdef CONFIG_X86_32
  86. .ss0 = __KERNEL_DS,
  87. .ss1 = __KERNEL_CS,
  88. --
  89. 2.14.2