* [PATCH v5 0/2] x86_64: fix KASan shadow region page tables
@ 2015-06-09 9:41 Alexander Popov
2015-06-09 9:42 ` [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page Alexander Popov
2015-06-09 9:42 ` [PATCH v5 2/2] x86_64: fix KASan shadow region page tables Alexander Popov
0 siblings, 2 replies; 9+ messages in thread
From: Alexander Popov @ 2015-06-09 9:41 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov,
Andrew Morton, Andrey Ryabinin, Andy Lutomirski,
Alexander Kuleshov, Denys Vlasenko, Borislav Petkov,
Peter Zijlstra, Kees Cook, Alexander Popov, x86, linux-kernel
This patch series:
- fixes kernel halt caused by incorrect physical addresses
in KASan shadow region page tables in case of non-zero phys_base;
- consolidates early KASan initialization.
Changes from v2:
- move KASan shadow region page tables to BSS;
- use __PAGE_KERNEL flags for describing kasan_zero_page in kasan_zero_pte.
Changes from v3:
- improve commit message.
Changes from v4:
- add Andrey's patch which removes faulty clear_page(init_level4_pgt);
- call kasan_map_early_shadow() for early_level4_pgt and init_level4_pgt
in kasan_early_init().
Alexander Popov (1):
x86_64: fix KASan shadow region page tables
Andrey Ryabinin (1):
x86_64: remove not needed clear_page for init_level4_page
arch/x86/include/asm/kasan.h | 8 ++------
arch/x86/kernel/head64.c | 12 ++++++------
arch/x86/kernel/head_64.S | 29 -----------------------------
arch/x86/mm/kasan_init_64.c | 36 ++++++++++++++++++++++++++++++++++--
4 files changed, 42 insertions(+), 43 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page 2015-06-09 9:41 [PATCH v5 0/2] x86_64: fix KASan shadow region page tables Alexander Popov @ 2015-06-09 9:42 ` Alexander Popov 2015-06-16 11:16 ` Borislav Petkov 2015-06-09 9:42 ` [PATCH v5 2/2] x86_64: fix KASan shadow region page tables Alexander Popov 1 sibling, 1 reply; 9+ messages in thread From: Alexander Popov @ 2015-06-09 9:42 UTC (permalink / raw) To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andrey Ryabinin, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Borislav Petkov, Peter Zijlstra, Kees Cook, Alexander Popov, x86, linux-kernel From: Andrey Ryabinin <a.ryabinin@samsung.com> Commit 8170e6bed465 ("x86, 64bit: Use a #PF handler to materialize early mappings on demand") introduced clear_page(init_level4_pgt); call in x86_64_start_kernel(). However, this clear_page is useless because init_level4_page already filled with zeroes in head_64.S Commit message in 8170e6bed465 says that this clear_page() was dropped in v7, but it accidentally reappeared in later versions of that patchset. Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com> --- arch/x86/kernel/head64.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 5a46681..6a6eefd 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -177,7 +177,6 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) */ load_ucode_bsp(); - clear_page(init_level4_pgt); /* set init_level4_pgt kernel high mapping*/ init_level4_pgt[511] = early_level4_pgt[511]; -- 1.9.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page 2015-06-09 9:42 ` [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page Alexander Popov @ 2015-06-16 11:16 ` Borislav Petkov 2015-06-16 11:34 ` Borislav Petkov 0 siblings, 1 reply; 9+ messages in thread From: Borislav Petkov @ 2015-06-16 11:16 UTC (permalink / raw) To: Alexander Popov Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andrey Ryabinin, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Peter Zijlstra, Kees Cook, x86, linux-kernel On Tue, Jun 09, 2015 at 12:42:00PM +0300, Alexander Popov wrote: > From: Andrey Ryabinin <a.ryabinin@samsung.com> > > Commit 8170e6bed465 ("x86, 64bit: Use a #PF handler to materialize > early mappings on demand") introduced clear_page(init_level4_pgt); > call in x86_64_start_kernel(). However, this clear_page is useless > because init_level4_page already filled with zeroes in head_64.S I really doubt that, see below: > Commit message in 8170e6bed465 says that this clear_page() was > dropped in v7, but it accidentally reappeared in later versions > of that patchset. > > Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com> > --- > arch/x86/kernel/head64.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c > index 5a46681..6a6eefd 100644 > --- a/arch/x86/kernel/head64.c > +++ b/arch/x86/kernel/head64.c > @@ -177,7 +177,6 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) > */ > load_ucode_bsp(); > > - clear_page(init_level4_pgt); > /* set init_level4_pgt kernel high mapping*/ > init_level4_pgt[511] = early_level4_pgt[511]; vmlinux has: ffffffff81a00000 <init_level4_pgt>: ffffffff81a00000: 63 10 movslq (%rax),%edx ffffffff81a00002: a0 01 00 00 00 00 00 movabs 0x1,%al ffffffff81a00009: 00 00 ... ffffffff81a0087f: 00 63 10 add %ah,0x10(%rbx) ffffffff81a00882: a0 01 00 00 00 00 00 movabs 0x1,%al ffffffff81a00889: 00 00 ... ffffffff81a00ff7: 00 67 30 add %ah,0x30(%rdi) ffffffff81a00ffa: a0 01 00 00 00 00 63 movabs 0xa020630000000001,%al ffffffff81a01001: 20 a0 ffffffff81a01000 <level3_ident_pgt>: ffffffff81a01000: 63 20 movslq (%rax),%esp ffffffff81a01002: a0 01 00 00 00 00 00 movabs 0x1,%al ffffffff81a01009: 00 00 ... Booting a kvm quest and halting it before the clear_page: --- /* * Load microcode early on BSP. */ load_ucode_bsp(); // clear_page(init_level4_pgt); while(1) cpu_relax(); /* set init_level4_pgt kernel high mapping*/ init_level4_pgt[511] = early_level4_pgt[511]; --- and dumping the memory at ffffffff81a00000 gives: --- 00000000 63 10 a0 01 00 00 00 00 00 00 00 00 00 00 00 00 |c...............| 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000880 63 10 a0 01 00 00 00 00 00 00 00 00 00 00 00 00 |c...............| 00000890 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000ff0 00 00 00 00 00 00 00 00 67 30 a0 01 00 00 00 00 |........g0......| 00001000 --- These are basically the PTE entries it gets for the CONFIG_XEN case which we clear because we're on baremetal. Now my hunch is that those entries get overwritten later but I wouldn't want to debug any strange bugs from leftovers in init_level4_pgt so having the clear_page() is actually a good thing. -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. -- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page 2015-06-16 11:16 ` Borislav Petkov @ 2015-06-16 11:34 ` Borislav Petkov 2015-06-16 11:45 ` Andrey Ryabinin 0 siblings, 1 reply; 9+ messages in thread From: Borislav Petkov @ 2015-06-16 11:34 UTC (permalink / raw) To: Alexander Popov Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andrey Ryabinin, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Peter Zijlstra, Kees Cook, x86, linux-kernel On Tue, Jun 16, 2015 at 01:16:32PM +0200, Borislav Petkov wrote: > Now my hunch is that those entries get overwritten later but I wouldn't > want to debug any strange bugs from leftovers in init_level4_pgt so > having the clear_page() is actually a good thing. So I guess we can do that: #ifndef CONFIG_KASAN clear_page(init_level4_pgt); #endif Hmm... -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. -- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page 2015-06-16 11:34 ` Borislav Petkov @ 2015-06-16 11:45 ` Andrey Ryabinin 2015-06-16 15:46 ` Borislav Petkov 0 siblings, 1 reply; 9+ messages in thread From: Andrey Ryabinin @ 2015-06-16 11:45 UTC (permalink / raw) To: Borislav Petkov, Alexander Popov Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Peter Zijlstra, Kees Cook, x86, linux-kernel On 06/16/2015 02:34 PM, Borislav Petkov wrote: > On Tue, Jun 16, 2015 at 01:16:32PM +0200, Borislav Petkov wrote: >> Now my hunch is that those entries get overwritten later but I wouldn't >> want to debug any strange bugs from leftovers in init_level4_pgt so >> having the clear_page() is actually a good thing. > > So I guess we can do that: > > #ifndef CONFIG_KASAN > clear_page(init_level4_pgt); > #endif > Ugh.. Can't we just move clear_page(init_level4_pgt) higher? Before or right after clear_bss() (iow before kasan_early_init()). ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page 2015-06-16 11:45 ` Andrey Ryabinin @ 2015-06-16 15:46 ` Borislav Petkov 2015-06-17 11:43 ` Alexander Popov 0 siblings, 1 reply; 9+ messages in thread From: Borislav Petkov @ 2015-06-16 15:46 UTC (permalink / raw) To: Andrey Ryabinin Cc: Alexander Popov, Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Peter Zijlstra, Kees Cook, x86, linux-kernel On Tue, Jun 16, 2015 at 02:45:06PM +0300, Andrey Ryabinin wrote: > Can't we just move clear_page(init_level4_pgt) higher? Before or right > after clear_bss() (iow before kasan_early_init()). That sounds much better. And I don't see anything depending on init_level4_pgt before we clear it. And it boots here if I move it before kasan_map_early_shadow(early_level4_pgt); -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. -- ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page 2015-06-16 15:46 ` Borislav Petkov @ 2015-06-17 11:43 ` Alexander Popov 0 siblings, 0 replies; 9+ messages in thread From: Alexander Popov @ 2015-06-17 11:43 UTC (permalink / raw) To: Borislav Petkov, Andrey Ryabinin Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Peter Zijlstra, Kees Cook, x86, linux-kernel On 16.06.2015 18:46, Borislav Petkov wrote: > On Tue, Jun 16, 2015 at 02:45:06PM +0300, Andrey Ryabinin wrote: >> Can't we just move clear_page(init_level4_pgt) higher? Before or right >> after clear_bss() (iow before kasan_early_init()). > > That sounds much better. And I don't see anything depending on > init_level4_pgt before we clear it. And it boots here if I move it > before > > kasan_map_early_shadow(early_level4_pgt); Thanks, Borislav and Andrey. I'll return with version 6. Best regards, Alexander ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v5 2/2] x86_64: fix KASan shadow region page tables 2015-06-09 9:41 [PATCH v5 0/2] x86_64: fix KASan shadow region page tables Alexander Popov 2015-06-09 9:42 ` [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page Alexander Popov @ 2015-06-09 9:42 ` Alexander Popov 2015-06-12 17:13 ` Andrey Ryabinin 1 sibling, 1 reply; 9+ messages in thread From: Alexander Popov @ 2015-06-09 9:42 UTC (permalink / raw) To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andrey Ryabinin, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Borislav Petkov, Peter Zijlstra, Kees Cook, Alexander Popov, x86, linux-kernel Physical addresses in KASan shadow region page tables need fixup similarly to the other page tables. Current code doesn't do it which causes kernel halt if phys_base is not zero. So let's initialize KASan shadow region page tables in kasan_early_init() using __pa_nodebug() which considers phys_base. Signed-off-by: Alexander Popov <alpopov@ptsecurity.com> --- arch/x86/include/asm/kasan.h | 8 ++------ arch/x86/kernel/head64.c | 11 ++++++----- arch/x86/kernel/head_64.S | 29 ----------------------------- arch/x86/mm/kasan_init_64.c | 36 ++++++++++++++++++++++++++++++++++-- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h index 8b22422..74a2a8d 100644 --- a/arch/x86/include/asm/kasan.h +++ b/arch/x86/include/asm/kasan.h @@ -14,15 +14,11 @@ #ifndef __ASSEMBLY__ -extern pte_t kasan_zero_pte[]; -extern pte_t kasan_zero_pmd[]; -extern pte_t kasan_zero_pud[]; - #ifdef CONFIG_KASAN -void __init kasan_map_early_shadow(pgd_t *pgd); +void __init kasan_early_init(void); void __init kasan_init(void); #else -static inline void kasan_map_early_shadow(pgd_t *pgd) { } +static inline void kasan_early_init(void) { } static inline void kasan_init(void) { } #endif diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 6a6eefd..74da193 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -161,11 +161,14 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) /* Kill off the identity-map trampoline */ reset_early_page_tables(); - kasan_map_early_shadow(early_level4_pgt); - - /* clear bss before set_intr_gate with early_idt_handler */ + /* + * Clear bss before kasan_early_init and set_intr_gate + * with early_idt_handler + */ clear_bss(); + kasan_early_init(); + for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) set_intr_gate(i, early_idt_handler_array[i]); load_idt((const struct desc_ptr *)&idt_descr); @@ -180,8 +183,6 @@ asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) /* set init_level4_pgt kernel high mapping*/ init_level4_pgt[511] = early_level4_pgt[511]; - kasan_map_early_shadow(init_level4_pgt); - x86_64_start_reservations(real_mode_data); } diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index df7e780..7e5da2c 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -516,38 +516,9 @@ ENTRY(phys_base) /* This must match the first entry in level2_kernel_pgt */ .quad 0x0000000000000000 -#ifdef CONFIG_KASAN -#define FILL(VAL, COUNT) \ - .rept (COUNT) ; \ - .quad (VAL) ; \ - .endr - -NEXT_PAGE(kasan_zero_pte) - FILL(kasan_zero_page - __START_KERNEL_map + _KERNPG_TABLE, 512) -NEXT_PAGE(kasan_zero_pmd) - FILL(kasan_zero_pte - __START_KERNEL_map + _KERNPG_TABLE, 512) -NEXT_PAGE(kasan_zero_pud) - FILL(kasan_zero_pmd - __START_KERNEL_map + _KERNPG_TABLE, 512) - -#undef FILL -#endif - - #include "../../x86/xen/xen-head.S" __PAGE_ALIGNED_BSS NEXT_PAGE(empty_zero_page) .skip PAGE_SIZE -#ifdef CONFIG_KASAN -/* - * This page used as early shadow. We don't use empty_zero_page - * at early stages, stack instrumentation could write some garbage - * to this page. - * Latter we reuse it as zero shadow for large ranges of memory - * that allowed to access, but not instrumented by kasan - * (vmalloc/vmemmap ...). - */ -NEXT_PAGE(kasan_zero_page) - .skip PAGE_SIZE -#endif diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c index 4860906..0e4a05f 100644 --- a/arch/x86/mm/kasan_init_64.c +++ b/arch/x86/mm/kasan_init_64.c @@ -11,7 +11,19 @@ extern pgd_t early_level4_pgt[PTRS_PER_PGD]; extern struct range pfn_mapped[E820_X_MAX]; -extern unsigned char kasan_zero_page[PAGE_SIZE]; +static pud_t kasan_zero_pud[PTRS_PER_PUD] __page_aligned_bss; +static pmd_t kasan_zero_pmd[PTRS_PER_PMD] __page_aligned_bss; +static pte_t kasan_zero_pte[PTRS_PER_PTE] __page_aligned_bss; + +/* + * This page used as early shadow. We don't use empty_zero_page + * at early stages, stack instrumentation could write some garbage + * to this page. + * Latter we reuse it as zero shadow for large ranges of memory + * that allowed to access, but not instrumented by kasan + * (vmalloc/vmemmap ...). + */ +static unsigned char kasan_zero_page[PAGE_SIZE] __page_aligned_bss; static int __init map_range(struct range *range) { @@ -36,7 +48,7 @@ static void __init clear_pgds(unsigned long start, pgd_clear(pgd_offset_k(start)); } -void __init kasan_map_early_shadow(pgd_t *pgd) +static void __init kasan_map_early_shadow(pgd_t *pgd) { int i; unsigned long start = KASAN_SHADOW_START; @@ -166,6 +178,26 @@ static struct notifier_block kasan_die_notifier = { }; #endif +void __init kasan_early_init(void) +{ + int i; + pteval_t pte_val = __pa_nodebug(kasan_zero_page) | __PAGE_KERNEL; + pmdval_t pmd_val = __pa_nodebug(kasan_zero_pte) | _KERNPG_TABLE; + pudval_t pud_val = __pa_nodebug(kasan_zero_pmd) | _KERNPG_TABLE; + + for (i = 0; i < PTRS_PER_PTE; i++) + kasan_zero_pte[i] = __pte(pte_val); + + for (i = 0; i < PTRS_PER_PMD; i++) + kasan_zero_pmd[i] = __pmd(pmd_val); + + for (i = 0; i < PTRS_PER_PUD; i++) + kasan_zero_pud[i] = __pud(pud_val); + + kasan_map_early_shadow(early_level4_pgt); + kasan_map_early_shadow(init_level4_pgt); +} + void __init kasan_init(void) { int i; -- 1.9.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v5 2/2] x86_64: fix KASan shadow region page tables 2015-06-09 9:42 ` [PATCH v5 2/2] x86_64: fix KASan shadow region page tables Alexander Popov @ 2015-06-12 17:13 ` Andrey Ryabinin 0 siblings, 0 replies; 9+ messages in thread From: Andrey Ryabinin @ 2015-06-12 17:13 UTC (permalink / raw) To: Alexander Popov Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov, Andrew Morton, Andrey Ryabinin, Andy Lutomirski, Alexander Kuleshov, Denys Vlasenko, Borislav Petkov, Peter Zijlstra, Kees Cook, x86@kernel.org, LKML 2015-06-09 12:42 GMT+03:00 Alexander Popov <alpopov@ptsecurity.com>: > Physical addresses in KASan shadow region page tables need fixup similarly > to the other page tables. Current code doesn't do it which causes > kernel halt if phys_base is not zero. > So let's initialize KASan shadow region page tables in kasan_early_init() > using __pa_nodebug() which considers phys_base. > > Signed-off-by: Alexander Popov <alpopov@ptsecurity.com> Acked-by: Andrey Ryabinin <a.ryabinin@samsung.com> ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-06-17 11:42 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-06-09 9:41 [PATCH v5 0/2] x86_64: fix KASan shadow region page tables Alexander Popov 2015-06-09 9:42 ` [PATCH v5 1/2] x86_64: remove not needed clear_page for init_level4_page Alexander Popov 2015-06-16 11:16 ` Borislav Petkov 2015-06-16 11:34 ` Borislav Petkov 2015-06-16 11:45 ` Andrey Ryabinin 2015-06-16 15:46 ` Borislav Petkov 2015-06-17 11:43 ` Alexander Popov 2015-06-09 9:42 ` [PATCH v5 2/2] x86_64: fix KASan shadow region page tables Alexander Popov 2015-06-12 17:13 ` Andrey Ryabinin
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox