]> git.proxmox.com Git - pve-kernel.git/blame - patches/kernel/0217-x86-mm-dump_pagetables-Allow-dumping-current-pagetab.patch
KPTI: add follow-up fixes
[pve-kernel.git] / patches / kernel / 0217-x86-mm-dump_pagetables-Allow-dumping-current-pagetab.patch
CommitLineData
321d628a
FG
1From 0a708f5b66f8b49338f8cf8b6d84d3fdc7b3f67f Mon Sep 17 00:00:00 2001
2From: Thomas Gleixner <tglx@linutronix.de>
3Date: Mon, 4 Dec 2017 15:08:06 +0100
e4cdf2a5 4Subject: [PATCH 217/241] x86/mm/dump_pagetables: Allow dumping current
321d628a
FG
5 pagetables
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10CVE-2017-5754
11
12Add two debugfs files which allow to dump the pagetable of the current
13task.
14
15current_kernel dumps the regular page table. This is the page table which
16is normally shared between kernel and user space. If kernel page table
17isolation is enabled this is the kernel space mapping.
18
19If kernel page table isolation is enabled the second file, current_user,
20dumps the user space page table.
21
22These files allow to verify the resulting page tables for page table
23isolation, but even in the normal case its useful to be able to inspect
24user space page tables of current for debugging purposes.
25
26Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
27Cc: Andy Lutomirski <luto@kernel.org>
28Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
29Cc: Borislav Petkov <bp@alien8.de>
30Cc: Brian Gerst <brgerst@gmail.com>
31Cc: Dave Hansen <dave.hansen@linux.intel.com>
32Cc: David Laight <David.Laight@aculab.com>
33Cc: Denys Vlasenko <dvlasenk@redhat.com>
34Cc: Eduardo Valentin <eduval@amazon.com>
35Cc: Greg KH <gregkh@linuxfoundation.org>
36Cc: H. Peter Anvin <hpa@zytor.com>
37Cc: Josh Poimboeuf <jpoimboe@redhat.com>
38Cc: Juergen Gross <jgross@suse.com>
39Cc: Linus Torvalds <torvalds@linux-foundation.org>
40Cc: Peter Zijlstra <peterz@infradead.org>
41Cc: Will Deacon <will.deacon@arm.com>
42Cc: aliguori@amazon.com
43Cc: daniel.gruss@iaik.tugraz.at
44Cc: hughd@google.com
45Cc: keescook@google.com
46Cc: linux-mm@kvack.org
47Signed-off-by: Ingo Molnar <mingo@kernel.org>
48(cherry picked from commit a4b51ef6552c704764684cef7e753162dc87c5fa)
49Signed-off-by: Andy Whitcroft <apw@canonical.com>
50Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
51(cherry picked from commit e31e0526cb47bd1d848fc3fdb10d2aeb909e46b5)
52Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
53---
54 arch/x86/include/asm/pgtable.h | 2 +-
55 arch/x86/mm/debug_pagetables.c | 71 +++++++++++++++++++++++++++++++++++++++---
56 arch/x86/mm/dump_pagetables.c | 6 +++-
57 3 files changed, 73 insertions(+), 6 deletions(-)
58
59diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
60index 4f5eb81cf8be..1f9e7fea3c06 100644
61--- a/arch/x86/include/asm/pgtable.h
62+++ b/arch/x86/include/asm/pgtable.h
63@@ -17,7 +17,7 @@
64 #include <asm/x86_init.h>
65
66 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
67-void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
68+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user);
69 void ptdump_walk_pgd_level_checkwx(void);
70
71 #ifdef CONFIG_DEBUG_WX
72diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
73index 8e70c1599e51..421f2664ffa0 100644
74--- a/arch/x86/mm/debug_pagetables.c
75+++ b/arch/x86/mm/debug_pagetables.c
76@@ -5,7 +5,7 @@
77
78 static int ptdump_show(struct seq_file *m, void *v)
79 {
80- ptdump_walk_pgd_level_debugfs(m, NULL);
81+ ptdump_walk_pgd_level_debugfs(m, NULL, false);
82 return 0;
83 }
84
85@@ -22,7 +22,57 @@ static const struct file_operations ptdump_fops = {
86 .release = single_release,
87 };
88
89-static struct dentry *dir, *pe;
90+static int ptdump_show_curknl(struct seq_file *m, void *v)
91+{
92+ if (current->mm->pgd) {
93+ down_read(&current->mm->mmap_sem);
94+ ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
95+ up_read(&current->mm->mmap_sem);
96+ }
97+ return 0;
98+}
99+
100+static int ptdump_open_curknl(struct inode *inode, struct file *filp)
101+{
102+ return single_open(filp, ptdump_show_curknl, NULL);
103+}
104+
105+static const struct file_operations ptdump_curknl_fops = {
106+ .owner = THIS_MODULE,
107+ .open = ptdump_open_curknl,
108+ .read = seq_read,
109+ .llseek = seq_lseek,
110+ .release = single_release,
111+};
112+
113+#ifdef CONFIG_PAGE_TABLE_ISOLATION
114+static struct dentry *pe_curusr;
115+
116+static int ptdump_show_curusr(struct seq_file *m, void *v)
117+{
118+ if (current->mm->pgd) {
119+ down_read(&current->mm->mmap_sem);
120+ ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
121+ up_read(&current->mm->mmap_sem);
122+ }
123+ return 0;
124+}
125+
126+static int ptdump_open_curusr(struct inode *inode, struct file *filp)
127+{
128+ return single_open(filp, ptdump_show_curusr, NULL);
129+}
130+
131+static const struct file_operations ptdump_curusr_fops = {
132+ .owner = THIS_MODULE,
133+ .open = ptdump_open_curusr,
134+ .read = seq_read,
135+ .llseek = seq_lseek,
136+ .release = single_release,
137+};
138+#endif
139+
140+static struct dentry *dir, *pe_knl, *pe_curknl;
141
142 static int __init pt_dump_debug_init(void)
143 {
144@@ -30,9 +80,22 @@ static int __init pt_dump_debug_init(void)
145 if (!dir)
146 return -ENOMEM;
147
148- pe = debugfs_create_file("kernel", 0400, dir, NULL, &ptdump_fops);
149- if (!pe)
150+ pe_knl = debugfs_create_file("kernel", 0400, dir, NULL,
151+ &ptdump_fops);
152+ if (!pe_knl)
153+ goto err;
154+
155+ pe_curknl = debugfs_create_file("current_kernel", 0400,
156+ dir, NULL, &ptdump_curknl_fops);
157+ if (!pe_curknl)
158+ goto err;
159+
160+#ifdef CONFIG_PAGE_TABLE_ISOLATION
161+ pe_curusr = debugfs_create_file("current_user", 0400,
162+ dir, NULL, &ptdump_curusr_fops);
163+ if (!pe_curusr)
164 goto err;
165+#endif
166 return 0;
167 err:
168 debugfs_remove_recursive(dir);
169diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
170index 7b022ad37c4e..12b93d350480 100644
171--- a/arch/x86/mm/dump_pagetables.c
172+++ b/arch/x86/mm/dump_pagetables.c
173@@ -511,8 +511,12 @@ void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
174 ptdump_walk_pgd_level_core(m, pgd, false, true);
175 }
176
177-void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
178+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user)
179 {
180+#ifdef CONFIG_PAGE_TABLE_ISOLATION
181+ if (user && static_cpu_has(X86_FEATURE_PTI))
182+ pgd = kernel_to_user_pgdp(pgd);
183+#endif
184 ptdump_walk_pgd_level_core(m, pgd, false, false);
185 }
186 EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
187--
1882.14.2
189