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

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