x86/mm/dump_pagetables: Check user space page table for WX pages
authorThomas Gleixner <tglx@linutronix.de>
Mon, 4 Dec 2017 14:08:05 +0000 (15:08 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Jan 2018 19:31:02 +0000 (20:31 +0100)
commit b4bf4f924b1d7bade38fd51b2e401d20d0956e4d upstream.

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: David Laight <David.Laight@aculab.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Eduardo Valentin <eduval@amazon.com>
Cc: Greg KH <gregkh@linuxfoundation.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: aliguori@amazon.com
Cc: daniel.gruss@iaik.tugraz.at
Cc: hughd@google.com
Cc: keescook@google.com
Cc: linux-mm@kvack.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/include/asm/pgtable.h
arch/x86/mm/debug_pagetables.c
arch/x86/mm/dump_pagetables.c

index 9aaeea68783469b1e6bcf3da5ecadd8013ab6bf4..6b8bd9016eeb7345278e7ecf08b54f1a17055c22 100644 (file)
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
index d1449fb6dc7a0d495284625c3001bb873202a51e..8e70c1599e517f5b78c2fb957b91e8baa474dae9 100644 (file)
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-       ptdump_walk_pgd_level(m, NULL);
+       ptdump_walk_pgd_level_debugfs(m, NULL);
        return 0;
 }
 
index 690eaf31ca342146a772c8812e249577d7813ff3..17f5b417f95e9e869aca7c07cadccf9e4c0c9890 100644 (file)
@@ -476,7 +476,7 @@ static inline bool is_hypervisor_range(int idx)
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-                                      bool checkwx)
+                                      bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
        pgd_t *start = (pgd_t *) &init_top_pgt;
@@ -489,7 +489,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
 
        if (pgd) {
                start = pgd;
-               st.to_dmesg = true;
+               st.to_dmesg = dmesg;
        }
 
        st.check_wx = checkwx;
@@ -527,13 +527,33 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-       ptdump_walk_pgd_level_core(m, pgd, false);
+       ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+       ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+       pgd_t *pgd = (pgd_t *) &init_top_pgt;
+
+       if (!static_cpu_has(X86_FEATURE_PTI))
+               return;
+
+       pr_info("x86/mm: Checking user space page tables\n");
+       pgd = kernel_to_user_pgdp(pgd);
+       ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-       ptdump_walk_pgd_level_core(NULL, NULL, true);
+       ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+       ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)