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