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