Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b4bf4f92 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Ingo Molnar
Browse files

x86/mm/dump_pagetables: Check user space page table for WX pages



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: default avatarThomas 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: default avatarIngo Molnar <mingo@kernel.org>
parent 75298aa1
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
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(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);
void ptdump_walk_pgd_level_checkwx(void);


#ifdef CONFIG_DEBUG_WX
#ifdef CONFIG_DEBUG_WX
+1 −1
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@


static int ptdump_show(struct seq_file *m, void *v)
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;
	return 0;
}
}


+25 −5
Original line number Original line Diff line number Diff line
@@ -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,
static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
				       bool checkwx)
				       bool checkwx, bool dmesg)
{
{
#ifdef CONFIG_X86_64
#ifdef CONFIG_X86_64
	pgd_t *start = (pgd_t *) &init_top_pgt;
	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) {
	if (pgd) {
		start = pgd;
		start = pgd;
		st.to_dmesg = true;
		st.to_dmesg = dmesg;
	}
	}


	st.check_wx = checkwx;
	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)
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)
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)
static int __init pt_dump_init(void)