0044-x86-mm-64-Stop-using-CR3.PCID-0-in-ASID-aware-code.patch 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. From b5143e55b3bf018b3ad2598e677ceb5e155eba6f Mon Sep 17 00:00:00 2001
  2. From: Andy Lutomirski <[email protected]>
  3. Date: Sun, 17 Sep 2017 09:03:49 -0700
  4. Subject: [PATCH 044/242] x86/mm/64: Stop using CR3.PCID == 0 in ASID-aware
  5. code
  6. MIME-Version: 1.0
  7. Content-Type: text/plain; charset=UTF-8
  8. Content-Transfer-Encoding: 8bit
  9. CVE-2017-5754
  10. Putting the logical ASID into CR3's PCID bits directly means that we
  11. have two cases to consider separately: ASID == 0 and ASID != 0.
  12. This means that bugs that only hit in one of these cases trigger
  13. nondeterministically.
  14. There were some bugs like this in the past, and I think there's
  15. still one in current kernels. In particular, we have a number of
  16. ASID-unware code paths that save CR3, write some special value, and
  17. then restore CR3. This includes suspend/resume, hibernate, kexec,
  18. EFI, and maybe other things I've missed. This is currently
  19. dangerous: if ASID != 0, then this code sequence will leave garbage
  20. in the TLB tagged for ASID 0. We could potentially see corruption
  21. when switching back to ASID 0. In principle, an
  22. initialize_tlbstate_and_flush() call after these sequences would
  23. solve the problem, but EFI, at least, does not call this. (And it
  24. probably shouldn't -- initialize_tlbstate_and_flush() is rather
  25. expensive.)
  26. Signed-off-by: Andy Lutomirski <[email protected]>
  27. Cc: Borislav Petkov <[email protected]>
  28. Cc: Linus Torvalds <[email protected]>
  29. Cc: Peter Zijlstra <[email protected]>
  30. Cc: Thomas Gleixner <[email protected]>
  31. Link: http://lkml.kernel.org/r/cdc14bbe5d3c3ef2a562be09a6368ffe9bd947a6.1505663533.git.luto@kernel.org
  32. Signed-off-by: Ingo Molnar <[email protected]>
  33. (cherry picked from commit 52a2af400c1075219b3f0ce5c96fc961da44018a)
  34. Signed-off-by: Andy Whitcroft <[email protected]>
  35. Signed-off-by: Kleber Sacilotto de Souza <[email protected]>
  36. (cherry picked from commit 15e474753e66e44da1365049f465427053a453ba)
  37. Signed-off-by: Fabian Grünbichler <[email protected]>
  38. ---
  39. arch/x86/include/asm/mmu_context.h | 21 +++++++++++++++++++--
  40. 1 file changed, 19 insertions(+), 2 deletions(-)
  41. diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h
  42. index a999ba6b721f..c120b5db178a 100644
  43. --- a/arch/x86/include/asm/mmu_context.h
  44. +++ b/arch/x86/include/asm/mmu_context.h
  45. @@ -286,14 +286,31 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
  46. return __pkru_allows_pkey(vma_pkey(vma), write);
  47. }
  48. +/*
  49. + * If PCID is on, ASID-aware code paths put the ASID+1 into the PCID
  50. + * bits. This serves two purposes. It prevents a nasty situation in
  51. + * which PCID-unaware code saves CR3, loads some other value (with PCID
  52. + * == 0), and then restores CR3, thus corrupting the TLB for ASID 0 if
  53. + * the saved ASID was nonzero. It also means that any bugs involving
  54. + * loading a PCID-enabled CR3 with CR4.PCIDE off will trigger
  55. + * deterministically.
  56. + */
  57. +
  58. static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid)
  59. {
  60. - return __sme_pa(mm->pgd) | asid;
  61. + if (static_cpu_has(X86_FEATURE_PCID)) {
  62. + VM_WARN_ON_ONCE(asid > 4094);
  63. + return __sme_pa(mm->pgd) | (asid + 1);
  64. + } else {
  65. + VM_WARN_ON_ONCE(asid != 0);
  66. + return __sme_pa(mm->pgd);
  67. + }
  68. }
  69. static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid)
  70. {
  71. - return __sme_pa(mm->pgd) | asid | CR3_NOFLUSH;
  72. + VM_WARN_ON_ONCE(asid > 4094);
  73. + return __sme_pa(mm->pgd) | (asid + 1) | CR3_NOFLUSH;
  74. }
  75. /*
  76. --
  77. 2.14.2