0087-x86-entry-64-Split-the-IRET-to-user-and-IRET-to-kern.patch 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. From 6c390918ecf72524840bc174fb5f9d007db5a9a8 Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Thu, 2 Nov 2017 00:58:59 -0700
  4. Subject: [PATCH 087/231] x86/entry/64: Split the IRET-to-user and
  5. IRET-to-kernel paths
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. CVE-2017-5754
  10. These code paths will diverge soon.
  11. Signed-off-by: Andy Lutomirski <[email protected]>
  12. Cc: Borislav Petkov <[email protected]>
  13. Cc: Brian Gerst <[email protected]>
  14. Cc: Dave Hansen <[email protected]>
  15. Cc: Linus Torvalds <[email protected]>
  16. Cc: Peter Zijlstra <[email protected]>
  17. Cc: Thomas Gleixner <[email protected]>
  18. Link: http://lkml.kernel.org/r/dccf8c7b3750199b4b30383c812d4e2931811509.1509609304.git.luto@kernel.org
  19. Signed-off-by: Ingo Molnar <[email protected]>
  20. (cherry picked from commit 26c4ef9c49d8a0341f6d97ce2cfdd55d1236ed29)
  21. Signed-off-by: Andy Whitcroft <[email protected]>
  22. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  23. (cherry picked from commit 64adfba0aeb668304d171c383ac80b22158ec128)
  24. Signed-off-by: Fabian Grünbichler <[email protected]>
  25. ---
  26. arch/x86/entry/entry_64.S | 34 +++++++++++++++++++++++++---------
  27. arch/x86/entry/entry_64_compat.S | 2 +-
  28. arch/x86/kernel/head_64.S | 2 +-
  29. 3 files changed, 27 insertions(+), 11 deletions(-)
  30. diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
  31. index fac354ddf056..e546441fbec3 100644
  32. --- a/arch/x86/entry/entry_64.S
  33. +++ b/arch/x86/entry/entry_64.S
  34. @@ -321,7 +321,7 @@ syscall_return_via_sysret:
  35. opportunistic_sysret_failed:
  36. SWAPGS
  37. - jmp restore_regs_and_iret
  38. + jmp restore_regs_and_return_to_usermode
  39. END(entry_SYSCALL_64)
  40. ENTRY(stub_ptregs_64)
  41. @@ -423,7 +423,7 @@ ENTRY(ret_from_fork)
  42. call syscall_return_slowpath /* returns with IRQs disabled */
  43. TRACE_IRQS_ON /* user mode is traced as IRQS on */
  44. SWAPGS
  45. - jmp restore_regs_and_iret
  46. + jmp restore_regs_and_return_to_usermode
  47. 1:
  48. /* kernel thread */
  49. @@ -612,7 +612,20 @@ GLOBAL(retint_user)
  50. call prepare_exit_to_usermode
  51. TRACE_IRQS_IRETQ
  52. SWAPGS
  53. - jmp restore_regs_and_iret
  54. +
  55. +GLOBAL(restore_regs_and_return_to_usermode)
  56. +#ifdef CONFIG_DEBUG_ENTRY
  57. + /* Assert that pt_regs indicates user mode. */
  58. + testl $3, CS(%rsp)
  59. + jnz 1f
  60. + ud2
  61. +1:
  62. +#endif
  63. + RESTORE_EXTRA_REGS
  64. + RESTORE_C_REGS
  65. + REMOVE_PT_GPREGS_FROM_STACK 8
  66. + INTERRUPT_RETURN
  67. +
  68. /* Returning to kernel space */
  69. retint_kernel:
  70. @@ -632,11 +645,14 @@ retint_kernel:
  71. */
  72. TRACE_IRQS_IRETQ
  73. -/*
  74. - * At this label, code paths which return to kernel and to user,
  75. - * which come from interrupts/exception and from syscalls, merge.
  76. - */
  77. -GLOBAL(restore_regs_and_iret)
  78. +GLOBAL(restore_regs_and_return_to_kernel)
  79. +#ifdef CONFIG_DEBUG_ENTRY
  80. + /* Assert that pt_regs indicates kernel mode. */
  81. + testl $3, CS(%rsp)
  82. + jz 1f
  83. + ud2
  84. +1:
  85. +#endif
  86. RESTORE_EXTRA_REGS
  87. RESTORE_C_REGS
  88. REMOVE_PT_GPREGS_FROM_STACK 8
  89. @@ -1340,7 +1356,7 @@ ENTRY(nmi)
  90. * work, because we don't want to enable interrupts.
  91. */
  92. SWAPGS
  93. - jmp restore_regs_and_iret
  94. + jmp restore_regs_and_return_to_usermode
  95. .Lnmi_from_kernel:
  96. /*
  97. diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
  98. index d8468ba24be0..2b3a88feaa2b 100644
  99. --- a/arch/x86/entry/entry_64_compat.S
  100. +++ b/arch/x86/entry/entry_64_compat.S
  101. @@ -337,7 +337,7 @@ ENTRY(entry_INT80_compat)
  102. /* Go back to user mode. */
  103. TRACE_IRQS_ON
  104. SWAPGS
  105. - jmp restore_regs_and_iret
  106. + jmp restore_regs_and_return_to_usermode
  107. END(entry_INT80_compat)
  108. ALIGN
  109. diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
  110. index 4117c1e0b3d2..e785734980ad 100644
  111. --- a/arch/x86/kernel/head_64.S
  112. +++ b/arch/x86/kernel/head_64.S
  113. @@ -311,7 +311,7 @@ early_idt_handler_common:
  114. 20:
  115. decl early_recursion_flag(%rip)
  116. - jmp restore_regs_and_iret
  117. + jmp restore_regs_and_return_to_kernel
  118. END(early_idt_handler_common)
  119. __INITDATA
  120. --
  121. 2.14.2