]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0216-x86-mm-dump_pagetables-Check-user-space-page-table-f.patch
ad6a8cc8c04d693d3940ed19483ad52d38d4fd17
[pve-kernel.git] / patches / kernel / 0216-x86-mm-dump_pagetables-Check-user-space-page-table-f.patch
1 From 2ed23a29f6f9c736c86dcc8d8ab87cc670593503 Mon Sep 17 00:00:00 2001
2 From: Thomas Gleixner <tglx@linutronix.de>
3 Date: Mon, 4 Dec 2017 15:08:05 +0100
4 Subject: [PATCH 216/233] x86/mm/dump_pagetables: Check user space page table
5 for WX pages
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 ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
13 but does not check the PAGE_TABLE_ISOLATION user space page table.
14
15 Restructure the code so that dmesg output is selected by an explicit
16 argument and not implicit via checking the pgd argument for !NULL.
17
18 Add the check for the user space page table.
19
20 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
21 Cc: Andy Lutomirski <luto@kernel.org>
22 Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
23 Cc: Borislav Petkov <bp@alien8.de>
24 Cc: Brian Gerst <brgerst@gmail.com>
25 Cc: Dave Hansen <dave.hansen@linux.intel.com>
26 Cc: David Laight <David.Laight@aculab.com>
27 Cc: Denys Vlasenko <dvlasenk@redhat.com>
28 Cc: Eduardo Valentin <eduval@amazon.com>
29 Cc: Greg KH <gregkh@linuxfoundation.org>
30 Cc: H. Peter Anvin <hpa@zytor.com>
31 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
32 Cc: Juergen Gross <jgross@suse.com>
33 Cc: Linus Torvalds <torvalds@linux-foundation.org>
34 Cc: Peter Zijlstra <peterz@infradead.org>
35 Cc: Will Deacon <will.deacon@arm.com>
36 Cc: aliguori@amazon.com
37 Cc: daniel.gruss@iaik.tugraz.at
38 Cc: hughd@google.com
39 Cc: keescook@google.com
40 Cc: linux-mm@kvack.org
41 Signed-off-by: Ingo Molnar <mingo@kernel.org>
42 (cherry picked from commit b4bf4f924b1d7bade38fd51b2e401d20d0956e4d)
43 Signed-off-by: Andy Whitcroft <apw@canonical.com>
44 Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
45 (cherry picked from commit 1adfe82e8fe5afa2fae59efe498c461d5a52cb6c)
46 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
47 ---
48 arch/x86/include/asm/pgtable.h | 1 +
49 arch/x86/mm/debug_pagetables.c | 2 +-
50 arch/x86/mm/dump_pagetables.c | 30 +++++++++++++++++++++++++-----
51 3 files changed, 27 insertions(+), 6 deletions(-)
52
53 diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
54 index 25604b8a251a..4f5eb81cf8be 100644
55 --- a/arch/x86/include/asm/pgtable.h
56 +++ b/arch/x86/include/asm/pgtable.h
57 @@ -17,6 +17,7 @@
58 #include <asm/x86_init.h>
59
60 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
61 +void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
62 void ptdump_walk_pgd_level_checkwx(void);
63
64 #ifdef CONFIG_DEBUG_WX
65 diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
66 index d1449fb6dc7a..8e70c1599e51 100644
67 --- a/arch/x86/mm/debug_pagetables.c
68 +++ b/arch/x86/mm/debug_pagetables.c
69 @@ -5,7 +5,7 @@
70
71 static int ptdump_show(struct seq_file *m, void *v)
72 {
73 - ptdump_walk_pgd_level(m, NULL);
74 + ptdump_walk_pgd_level_debugfs(m, NULL);
75 return 0;
76 }
77
78 diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
79 index eed93dd4cb4a..7b022ad37c4e 100644
80 --- a/arch/x86/mm/dump_pagetables.c
81 +++ b/arch/x86/mm/dump_pagetables.c
82 @@ -457,7 +457,7 @@ static inline bool is_hypervisor_range(int idx)
83 }
84
85 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
86 - bool checkwx)
87 + bool checkwx, bool dmesg)
88 {
89 #ifdef CONFIG_X86_64
90 pgd_t *start = (pgd_t *) &init_top_pgt;
91 @@ -470,7 +470,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
92
93 if (pgd) {
94 start = pgd;
95 - st.to_dmesg = true;
96 + st.to_dmesg = dmesg;
97 }
98
99 st.check_wx = checkwx;
100 @@ -508,13 +508,33 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
101
102 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
103 {
104 - ptdump_walk_pgd_level_core(m, pgd, false);
105 + ptdump_walk_pgd_level_core(m, pgd, false, true);
106 +}
107 +
108 +void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
109 +{
110 + ptdump_walk_pgd_level_core(m, pgd, false, false);
111 +}
112 +EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
113 +
114 +static void ptdump_walk_user_pgd_level_checkwx(void)
115 +{
116 +#ifdef CONFIG_PAGE_TABLE_ISOLATION
117 + pgd_t *pgd = (pgd_t *) &init_top_pgt;
118 +
119 + if (!static_cpu_has(X86_FEATURE_PTI))
120 + return;
121 +
122 + pr_info("x86/mm: Checking user space page tables\n");
123 + pgd = kernel_to_user_pgdp(pgd);
124 + ptdump_walk_pgd_level_core(NULL, pgd, true, false);
125 +#endif
126 }
127 -EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
128
129 void ptdump_walk_pgd_level_checkwx(void)
130 {
131 - ptdump_walk_pgd_level_core(NULL, NULL, true);
132 + ptdump_walk_pgd_level_core(NULL, NULL, true, false);
133 + ptdump_walk_user_pgd_level_checkwx();
134 }
135
136 static int __init pt_dump_init(void)
137 --
138 2.14.2
139