0154-x86-entry-64-Return-to-userspace-from-the-trampoline.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. From eb1bbc0f0023eadafe368704180f4af739aca9a9 Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Mon, 4 Dec 2017 15:07:24 +0100
  4. Subject: [PATCH 154/242] x86/entry/64: Return to userspace from the trampoline
  5. stack
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. CVE-2017-5754
  10. By itself, this is useless. It gives us the ability to run some final code
  11. before exit that cannnot run on the kernel stack. This could include a CR3
  12. switch a la PAGE_TABLE_ISOLATION or some kernel stack erasing, for
  13. example. (Or even weird things like *changing* which kernel stack gets
  14. used as an ASLR-strengthening mechanism.)
  15. The SYSRET32 path is not covered yet. It could be in the future or
  16. we could just ignore it and force the slow path if needed.
  17. Signed-off-by: Andy Lutomirski <[email protected]>
  18. Signed-off-by: Thomas Gleixner <[email protected]>
  19. Reviewed-by: Thomas Gleixner <[email protected]>
  20. Reviewed-by: Borislav Petkov <[email protected]>
  21. Cc: Boris Ostrovsky <[email protected]>
  22. Cc: Borislav Petkov <[email protected]>
  23. Cc: Borislav Petkov <[email protected]>
  24. Cc: Brian Gerst <[email protected]>
  25. Cc: Dave Hansen <[email protected]>
  26. Cc: Dave Hansen <[email protected]>
  27. Cc: David Laight <[email protected]>
  28. Cc: Denys Vlasenko <[email protected]>
  29. Cc: Eduardo Valentin <[email protected]>
  30. Cc: Greg KH <[email protected]>
  31. Cc: H. Peter Anvin <[email protected]>
  32. Cc: Josh Poimboeuf <[email protected]>
  33. Cc: Juergen Gross <[email protected]>
  34. Cc: Linus Torvalds <[email protected]>
  35. Cc: Peter Zijlstra <[email protected]>
  36. Cc: Rik van Riel <[email protected]>
  37. Cc: Will Deacon <[email protected]>
  38. Cc: [email protected]
  39. Cc: [email protected]
  40. Cc: [email protected]
  41. Cc: [email protected]
  42. Link: https://lkml.kernel.org/r/[email protected]
  43. Signed-off-by: Ingo Molnar <[email protected]>
  44. (cherry picked from commit 3e3b9293d392c577b62e24e4bc9982320438e749)
  45. Signed-off-by: Andy Whitcroft <[email protected]>
  46. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  47. (cherry picked from commit 40eb58584f732a2fefb5959e79e408bedeaaa43c)
  48. Signed-off-by: Fabian Grünbichler <[email protected]>
  49. ---
  50. arch/x86/entry/entry_64.S | 55 +++++++++++++++++++++++++++++++++++++++++++----
  51. 1 file changed, 51 insertions(+), 4 deletions(-)
  52. diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
  53. index f70fedc58bac..4abe5b806d2a 100644
  54. --- a/arch/x86/entry/entry_64.S
  55. +++ b/arch/x86/entry/entry_64.S
  56. @@ -325,8 +325,24 @@ syscall_return_via_sysret:
  57. popq %rsi /* skip rcx */
  58. popq %rdx
  59. popq %rsi
  60. +
  61. + /*
  62. + * Now all regs are restored except RSP and RDI.
  63. + * Save old stack pointer and switch to trampoline stack.
  64. + */
  65. + movq %rsp, %rdi
  66. + movq PER_CPU_VAR(cpu_tss + TSS_sp0), %rsp
  67. +
  68. + pushq RSP-RDI(%rdi) /* RSP */
  69. + pushq (%rdi) /* RDI */
  70. +
  71. + /*
  72. + * We are on the trampoline stack. All regs except RDI are live.
  73. + * We can do future final exit work right here.
  74. + */
  75. +
  76. popq %rdi
  77. - movq RSP-ORIG_RAX(%rsp), %rsp
  78. + popq %rsp
  79. USERGS_SYSRET64
  80. END(entry_SYSCALL_64)
  81. @@ -629,10 +645,41 @@ GLOBAL(swapgs_restore_regs_and_return_to_usermode)
  82. ud2
  83. 1:
  84. #endif
  85. - SWAPGS
  86. POP_EXTRA_REGS
  87. - POP_C_REGS
  88. - addq $8, %rsp /* skip regs->orig_ax */
  89. + popq %r11
  90. + popq %r10
  91. + popq %r9
  92. + popq %r8
  93. + popq %rax
  94. + popq %rcx
  95. + popq %rdx
  96. + popq %rsi
  97. +
  98. + /*
  99. + * The stack is now user RDI, orig_ax, RIP, CS, EFLAGS, RSP, SS.
  100. + * Save old stack pointer and switch to trampoline stack.
  101. + */
  102. + movq %rsp, %rdi
  103. + movq PER_CPU_VAR(cpu_tss + TSS_sp0), %rsp
  104. +
  105. + /* Copy the IRET frame to the trampoline stack. */
  106. + pushq 6*8(%rdi) /* SS */
  107. + pushq 5*8(%rdi) /* RSP */
  108. + pushq 4*8(%rdi) /* EFLAGS */
  109. + pushq 3*8(%rdi) /* CS */
  110. + pushq 2*8(%rdi) /* RIP */
  111. +
  112. + /* Push user RDI on the trampoline stack. */
  113. + pushq (%rdi)
  114. +
  115. + /*
  116. + * We are on the trampoline stack. All regs except RDI are live.
  117. + * We can do future final exit work right here.
  118. + */
  119. +
  120. + /* Restore RDI. */
  121. + popq %rdi
  122. + SWAPGS
  123. INTERRUPT_RETURN
  124. --
  125. 2.14.2