0019-x86-entry-64-Initialize-the-top-of-the-IRQ-stack-bef.patch 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. From 63463bcffe420067411ad3d4d01b79c872fffc3a Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Tue, 11 Jul 2017 10:33:39 -0500
  4. Subject: [PATCH 019/242] x86/entry/64: Initialize the top of the IRQ stack
  5. before switching stacks
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. CVE-2017-5754
  10. The OOPS unwinder wants the word at the top of the IRQ stack to
  11. point back to the previous stack at all times when the IRQ stack
  12. is in use. There's currently a one-instruction window in ENTER_IRQ_STACK
  13. during which this isn't the case. Fix it by writing the old RSP to the
  14. top of the IRQ stack before jumping.
  15. This currently writes the pointer to the stack twice, which is a bit
  16. ugly. We could get rid of this by replacing irq_stack_ptr with
  17. irq_stack_ptr_minus_eight (better name welcome). OTOH, there may be
  18. all kinds of odd microarchitectural considerations in play that
  19. affect performance by a few cycles here.
  20. Reported-by: Mike Galbraith <[email protected]>
  21. Reported-by: Josh Poimboeuf <[email protected]>
  22. Signed-off-by: Andy Lutomirski <[email protected]>
  23. Signed-off-by: Josh Poimboeuf <[email protected]>
  24. Cc: Borislav Petkov <[email protected]>
  25. Cc: Brian Gerst <[email protected]>
  26. Cc: Denys Vlasenko <[email protected]>
  27. Cc: H. Peter Anvin <[email protected]>
  28. Cc: Jiri Slaby <[email protected]>
  29. Cc: Linus Torvalds <[email protected]>
  30. Cc: Peter Zijlstra <[email protected]>
  31. Cc: Thomas Gleixner <[email protected]>
  32. Cc: [email protected]
  33. Link: http://lkml.kernel.org/r/aae7e79e49914808440ad5310ace138ced2179ca.1499786555.git.jpoimboe@redhat.com
  34. Signed-off-by: Ingo Molnar <[email protected]>
  35. (cherry picked from commit 2995590964da93e1fd9a91550f9c9d9fab28f160)
  36. Signed-off-by: Andy Whitcroft <[email protected]>
  37. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  38. (cherry picked from commit a753ff654dfd07a7f8d6f39a27126589eac7e55f)
  39. Signed-off-by: Fabian Grünbichler <[email protected]>
  40. ---
  41. arch/x86/entry/entry_64.S | 24 +++++++++++++++++++++++-
  42. 1 file changed, 23 insertions(+), 1 deletion(-)
  43. diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
  44. index 07b4056af8a8..184b70712545 100644
  45. --- a/arch/x86/entry/entry_64.S
  46. +++ b/arch/x86/entry/entry_64.S
  47. @@ -469,6 +469,7 @@ END(irq_entries_start)
  48. DEBUG_ENTRY_ASSERT_IRQS_OFF
  49. movq %rsp, \old_rsp
  50. incl PER_CPU_VAR(irq_count)
  51. + jnz .Lirq_stack_push_old_rsp_\@
  52. /*
  53. * Right now, if we just incremented irq_count to zero, we've
  54. @@ -478,9 +479,30 @@ END(irq_entries_start)
  55. * it must be *extremely* careful to limit its stack usage. This
  56. * could include kprobes and a hypothetical future IST-less #DB
  57. * handler.
  58. + *
  59. + * The OOPS unwinder relies on the word at the top of the IRQ
  60. + * stack linking back to the previous RSP for the entire time we're
  61. + * on the IRQ stack. For this to work reliably, we need to write
  62. + * it before we actually move ourselves to the IRQ stack.
  63. + */
  64. +
  65. + movq \old_rsp, PER_CPU_VAR(irq_stack_union + IRQ_STACK_SIZE - 8)
  66. + movq PER_CPU_VAR(irq_stack_ptr), %rsp
  67. +
  68. +#ifdef CONFIG_DEBUG_ENTRY
  69. + /*
  70. + * If the first movq above becomes wrong due to IRQ stack layout
  71. + * changes, the only way we'll notice is if we try to unwind right
  72. + * here. Assert that we set up the stack right to catch this type
  73. + * of bug quickly.
  74. */
  75. + cmpq -8(%rsp), \old_rsp
  76. + je .Lirq_stack_okay\@
  77. + ud2
  78. + .Lirq_stack_okay\@:
  79. +#endif
  80. - cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
  81. +.Lirq_stack_push_old_rsp_\@:
  82. pushq \old_rsp
  83. .endm
  84. --
  85. 2.14.2