2015-06-18 07:36:01

by Alexander Popov

[permalink] [raw]
Subject: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

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 <[email protected]>
---

Notes:
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().

Changes from v5:
- restore clear_page(init_level4_pgt), but put it just after clear_bss()
to consolidate early KASan initialization;
- remove the comment which stopped bringing much profit to the code
readability. Otherwise describing all the new order dependences
would be too verbose.

arch/x86/include/asm/kasan.h | 8 ++------
arch/x86/kernel/head64.c | 10 ++++------
arch/x86/kernel/head_64.S | 29 -----------------------------
arch/x86/mm/kasan_init_64.c | 36 ++++++++++++++++++++++++++++++++++--
4 files changed, 40 insertions(+), 43 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 5a46681..f129a9a 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -161,11 +161,12 @@ 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();

+ clear_page(init_level4_pgt);
+
+ 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);
@@ -177,12 +178,9 @@ 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];

- 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


2015-06-18 09:09:21

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On Thu, Jun 18, 2015 at 10:36:52AM +0300, Alexander Popov wrote:
> 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 <[email protected]>
> ---
>
> Notes:
> 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().
>
> Changes from v5:
> - restore clear_page(init_level4_pgt), but put it just after clear_bss()
> to consolidate early KASan initialization;
> - remove the comment which stopped bringing much profit to the code
> readability. Otherwise describing all the new order dependences
> would be too verbose.
>
> arch/x86/include/asm/kasan.h | 8 ++------
> arch/x86/kernel/head64.c | 10 ++++------
> arch/x86/kernel/head_64.S | 29 -----------------------------
> arch/x86/mm/kasan_init_64.c | 36 ++++++++++++++++++++++++++++++++++--
> 4 files changed, 40 insertions(+), 43 deletions(-)

So I applied it ontop of rc8 and did enable KASAN, see attached .config.

Build log contains:

scripts/Makefile.kasan:23: CONFIG_KASAN: compiler does not support all options. Trying minimal configuration

and the guest booted up to here:

...
[ 0.000000] e820: [mem 0x80000000-0xfeffbfff] available for PCI devices
[ 0.000000] clocksource refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
[ 0.000000] setup_percpu: NR_CPUS:8 nr_cpumask_bits:8 nr_cpu_ids:8 nr_node_ids:1
[ 0.000000] PERCPU: Embedded 490 pages/cpu @ffff88006b400000 s1970136 r8192 d28712 u2097152
[ 0.000000] pcpu-alloc: s1970136 r8192 d28712 u2097152 alloc=1*2097152
[ 0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 515944
[ 0.000000] Kernel command line: root=/dev/sda1 resume=/dev/sdb1 debug ignore_loglevel log_buf_len=16M earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0
[ 0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[ 0.000000] xsave: enabled xstate_bv 0x7, cntxt size 0x340 using standard form
[ 0.000000] BUG: unable to handle kernel paging request at fffff94000000083
[ 0.000000] IP: [<ffffffff81219c2b>] __asan_store4+0x2b/0xb0
[ 0.000000] PGD 800000000208b161 PUD 208a063 PMD 2089063 PTE 8000000002088163
[ 0.000000] Oops: 0009 [#1] PREEMPT SMP KASAN
[ 0.000000] Modules linked in:
[ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.1.0-rc8+ #3
[ 0.000000] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
[ 0.000000] task: ffffffff81cbd580 ti: ffffffff81ca8000 task.ti: ffffffff81ca8000
[ 0.000000] RIP: 0010:[<ffffffff81219c2b>] [<ffffffff81219c2b>] __asan_store4+0x2b/0xb0
[ 0.000000] RSP: 0000:ffffffff81cafe18 EFLAGS: 00010082
[ 0.000000] RAX: fffff94000000083 RBX: ffffea0000000440 RCX: 0000000000000004
[ 0.000000] RDX: dffffc0000000000 RSI: 0000000000000004 RDI: ffffea000000041c
[ 0.000000] RBP: ffffffff81cafe48 R08: ffffffff82030ce8 R09: ffffffff81cafee8
[ 0.000000] R10: 0000000000000001 R11: 0000000000000001 R12: 000000000000000f
[ 0.000000] R13: ffffea0000000400 R14: 0000000000000010 R15: 0000000000000001
[ 0.000000] FS: 0000000000000000(0000) GS:ffff88006b400000(0000) knlGS:0000000000000000
[ 0.000000] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 0.000000] CR2: fffff94000000083 CR3: 0000000001cb8000 CR4: 00000000000406b0
[ 0.000000] Stack:
[ 0.000000] ffffffff81cafeb8 ffffffff81fcacc0 ffffffff81cafee8 ffffffff81cafee0
[ 0.000000] ffffffff81cafef0 ffffffff82030ce8 ffffffff81cafe98 ffffffff81f942f8
[ 0.000000] ffffffff82030cd0 0000000482030d40 0000000000099000 0000000000000099
[ 0.000000] Call Trace:
[ 0.000000] [<ffffffff81fcacc0>] ? __next_mem_range+0x2cf/0x309
[ 0.000000] [<ffffffff81f942f8>] __free_pages_bootmem+0x4d/0x10a
[ 0.000000] [<ffffffff81f98fab>] __free_memory_core+0x79/0x8d
[ 0.000000] [<ffffffff81f991fe>] free_all_bootmem+0x5f/0xe3
[ 0.000000] [<ffffffff81f892fc>] mem_init+0xe/0x4a
[ 0.000000] [<ffffffff81f6ff90>] start_kernel+0x2bb/0x500
[ 0.000000] [<ffffffff81f6f120>] ? early_idt_handler_array+0x120/0x120
[ 0.000000] [<ffffffff81f6f4a8>] x86_64_start_reservations+0x2a/0x2c
[ 0.000000] [<ffffffff81f6f5e3>] x86_64_start_kernel+0x139/0x148
[ 0.000000] Code: 55 48 b8 ff ff ff ff ff 7f ff ff 48 89 e5 48 83 ec 30 48 39 c7 76 59 48 89 f8 48 ba 00 00 00 00 00 fc ff df 48 c1 e8 03 48 01 d0 <66> 83 38 00 75 07 c9 c3 0f 1f 44 00 00 48 8d 4f 03 48 89 ce 48
[ 0.000000] RIP [<ffffffff81219c2b>] __asan_store4+0x2b/0xb0
[ 0.000000] RSP <ffffffff81cafe18>
[ 0.000000] CR2: fffff94000000083
[ 0.000000] ---[ end trace 1e56b2b303866485 ]---
[ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
[ 0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task!

Now, if this really is caused by a compiler shortcoming, I think the
build should be failed in the scripts/Makefile.kasan check instead of
continuing.

Thanks.

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--


Attachments:
(No filename) (5.81 kB)
.config (88.90 kB)
Download all attachments

2015-06-18 12:22:46

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On 06/18/2015 12:08 PM, Borislav Petkov wrote:
> On Thu, Jun 18, 2015 at 10:36:52AM +0300, Alexander Popov wrote:
>> 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 <[email protected]>
>> ---
>>
>> Notes:
>> 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().
>>
>> Changes from v5:
>> - restore clear_page(init_level4_pgt), but put it just after clear_bss()
>> to consolidate early KASan initialization;
>> - remove the comment which stopped bringing much profit to the code
>> readability. Otherwise describing all the new order dependences
>> would be too verbose.
>>
>> arch/x86/include/asm/kasan.h | 8 ++------
>> arch/x86/kernel/head64.c | 10 ++++------
>> arch/x86/kernel/head_64.S | 29 -----------------------------
>> arch/x86/mm/kasan_init_64.c | 36 ++++++++++++++++++++++++++++++++++--
>> 4 files changed, 40 insertions(+), 43 deletions(-)
>
> So I applied it ontop of rc8 and did enable KASAN, see attached .config.
>
> Build log contains:
>
> scripts/Makefile.kasan:23: CONFIG_KASAN: compiler does not support all options. Trying minimal configuration
>
> and the guest booted up to here:
>
> ...
> [ 0.000000] e820: [mem 0x80000000-0xfeffbfff] available for PCI devices
> [ 0.000000] clocksource refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns
> [ 0.000000] setup_percpu: NR_CPUS:8 nr_cpumask_bits:8 nr_cpu_ids:8 nr_node_ids:1
> [ 0.000000] PERCPU: Embedded 490 pages/cpu @ffff88006b400000 s1970136 r8192 d28712 u2097152
> [ 0.000000] pcpu-alloc: s1970136 r8192 d28712 u2097152 alloc=1*2097152
> [ 0.000000] pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3 [0] 4 [0] 5 [0] 6 [0] 7
> [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 515944
> [ 0.000000] Kernel command line: root=/dev/sda1 resume=/dev/sdb1 debug ignore_loglevel log_buf_len=16M earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0
> [ 0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
> [ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
> [ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
> [ 0.000000] xsave: enabled xstate_bv 0x7, cntxt size 0x340 using standard form
> [ 0.000000] BUG: unable to handle kernel paging request at fffff94000000083
> [ 0.000000] IP: [<ffffffff81219c2b>] __asan_store4+0x2b/0xb0
> [ 0.000000] PGD 800000000208b161 PUD 208a063 PMD 2089063 PTE 8000000002088163
> [ 0.000000] Oops: 0009 [#1] PREEMPT SMP KASAN
> [ 0.000000] Modules linked in:
> [ 0.000000] CPU: 0 PID: 0 Comm: swapper Not tainted 4.1.0-rc8+ #3
> [ 0.000000] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
> [ 0.000000] task: ffffffff81cbd580 ti: ffffffff81ca8000 task.ti: ffffffff81ca8000
> [ 0.000000] RIP: 0010:[<ffffffff81219c2b>] [<ffffffff81219c2b>] __asan_store4+0x2b/0xb0
> [ 0.000000] RSP: 0000:ffffffff81cafe18 EFLAGS: 00010082
> [ 0.000000] RAX: fffff94000000083 RBX: ffffea0000000440 RCX: 0000000000000004
> [ 0.000000] RDX: dffffc0000000000 RSI: 0000000000000004 RDI: ffffea000000041c
> [ 0.000000] RBP: ffffffff81cafe48 R08: ffffffff82030ce8 R09: ffffffff81cafee8
> [ 0.000000] R10: 0000000000000001 R11: 0000000000000001 R12: 000000000000000f
> [ 0.000000] R13: ffffea0000000400 R14: 0000000000000010 R15: 0000000000000001
> [ 0.000000] FS: 0000000000000000(0000) GS:ffff88006b400000(0000) knlGS:0000000000000000
> [ 0.000000] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [ 0.000000] CR2: fffff94000000083 CR3: 0000000001cb8000 CR4: 00000000000406b0
> [ 0.000000] Stack:
> [ 0.000000] ffffffff81cafeb8 ffffffff81fcacc0 ffffffff81cafee8 ffffffff81cafee0
> [ 0.000000] ffffffff81cafef0 ffffffff82030ce8 ffffffff81cafe98 ffffffff81f942f8
> [ 0.000000] ffffffff82030cd0 0000000482030d40 0000000000099000 0000000000000099
> [ 0.000000] Call Trace:
> [ 0.000000] [<ffffffff81fcacc0>] ? __next_mem_range+0x2cf/0x309
> [ 0.000000] [<ffffffff81f942f8>] __free_pages_bootmem+0x4d/0x10a
> [ 0.000000] [<ffffffff81f98fab>] __free_memory_core+0x79/0x8d
> [ 0.000000] [<ffffffff81f991fe>] free_all_bootmem+0x5f/0xe3
> [ 0.000000] [<ffffffff81f892fc>] mem_init+0xe/0x4a
> [ 0.000000] [<ffffffff81f6ff90>] start_kernel+0x2bb/0x500
> [ 0.000000] [<ffffffff81f6f120>] ? early_idt_handler_array+0x120/0x120
> [ 0.000000] [<ffffffff81f6f4a8>] x86_64_start_reservations+0x2a/0x2c
> [ 0.000000] [<ffffffff81f6f5e3>] x86_64_start_kernel+0x139/0x148
> [ 0.000000] Code: 55 48 b8 ff ff ff ff ff 7f ff ff 48 89 e5 48 83 ec 30 48 39 c7 76 59 48 89 f8 48 ba 00 00 00 00 00 fc ff df 48 c1 e8 03 48 01 d0 <66> 83 38 00 75 07 c9 c3 0f 1f 44 00 00 48 8d 4f 03 48 89 ce 48
> [ 0.000000] RIP [<ffffffff81219c2b>] __asan_store4+0x2b/0xb0
> [ 0.000000] RSP <ffffffff81cafe18>
> [ 0.000000] CR2: fffff94000000083
> [ 0.000000] ---[ end trace 1e56b2b303866485 ]---
> [ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task!
> [ 0.000000] ---[ end Kernel panic - not syncing: Attempted to kill the idle task!
>
> Now, if this really is caused by a compiler shortcoming, I think the
> build should be failed in the scripts/Makefile.kasan check instead of
> continuing.
>

Whatever compiler you use, it shouldn't crash.
I see on problem which should be fixed by patch below.
Could you please try it?

---
From: Andrey Ryabinin <[email protected]>
Subject: [PATCH] x86_64: kasan: flush tlbs after switching cr3

load_cr3() doesn't cause tlb_flush if PGE enabled.
This may cause tons of false positive reports or kernel crash.
To fix this __flush_tlb_all() should be called explicitly
after cr3 changed.

Signed-off-by: Andrey Ryabinin <[email protected]>
---
arch/x86/mm/kasan_init_64.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 0e4a05f..5d26642 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -208,6 +208,7 @@ void __init kasan_init(void)

memcpy(early_level4_pgt, init_level4_pgt, sizeof(early_level4_pgt));
load_cr3(early_level4_pgt);
+ __flush_tlb_all();

clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);

@@ -234,5 +235,6 @@ void __init kasan_init(void)
memset(kasan_zero_page, 0, PAGE_SIZE);

load_cr3(init_level4_pgt);
+ __flush_tlb_all();
init_task.kasan_depth = 0;
}
--
2.4.2



2015-06-18 14:55:59

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On Thu, Jun 18, 2015 at 03:22:25PM +0300, Andrey Ryabinin wrote:
> Whatever compiler you use, it shouldn't crash. I see on problem which
> should be fixed by patch below. Could you please try it?

Just did. No change.

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--

2015-06-18 16:05:17

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On 06/18/2015 05:55 PM, Borislav Petkov wrote:
> On Thu, Jun 18, 2015 at 03:22:25PM +0300, Andrey Ryabinin wrote:
>> Whatever compiler you use, it shouldn't crash. I see on problem which
>> should be fixed by patch below. Could you please try it?
>
> Just did. No change.
>

So this is a separate issue and unfortunately I can't reproduce it.
What qemu version do you use and how you run it (qemu's command line options)?

2015-06-18 16:39:05

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On Thu, Jun 18, 2015 at 07:05:04PM +0300, Andrey Ryabinin wrote:
> What qemu version do you use and how you run it (qemu's command line
> options)?

Here it is:

qemu-system-x86_64
-enable-kvm
-gdb tcp::1234
-cpu Opteron_G5
-m 2048
-hda /home/boris/kvm/x86_64.img
-hdb /home/boris/kvm/swap.img
-boot menu=off,order=c
-localtime
-net nic,model=rtl8139
-net user,hostfwd=tcp::1235-:22
-usbdevice tablet
-kernel /home/boris/kernel/linux-2.6/arch/x86/boot/bzImage
-append "root=/dev/sda1 resume=/dev/sdb1 debug ignore_loglevel log_buf_len=16M earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0"
-monitor pty
-virtfs local,path=/tmp,mount_tag=tmp,security_model=none
-serial file:/home/boris/kvm/test-x86_64-1235.log
-snapshot
-smp 8

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--

2015-06-19 11:49:35

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On 06/18/2015 07:38 PM, Borislav Petkov wrote:
> On Thu, Jun 18, 2015 at 07:05:04PM +0300, Andrey Ryabinin wrote:
>> What qemu version do you use and how you run it (qemu's command line
>> options)?
>
> Here it is:

> -cpu Opteron_G5

I guess that AMD cpus is more strict (unlike Intel) about violation
of reserved/unused bits in page table entries.
Please, try with this patch.

---
From: Andrey Ryabinin <[email protected]>
Subject: [PATCH] x86_64: kasan: one more fix for KASan zero shadow page
tables.

While populating zero shadow wrong bits in upper level page tables
used. __PAGE_KERNEL_RO that was used for pgd/pud/pmd has
_PAGE_BIT_GLOBAL set. Global bit is present only in the lowest
level of the page translation hierarchy (ptes), and it should be zero
in upper levels.
This bug seems doesn't cause any troubles on Intel cpus, while on AMDs
it crashes kernel.

Signed-off-by: Andrey Ryabinin <[email protected]>
---
arch/x86/mm/kasan_init_64.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 5d26642..9a54dbe 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -85,7 +85,7 @@ static int __init zero_pmd_populate(pud_t *pud, unsigned long addr,
while (IS_ALIGNED(addr, PMD_SIZE) && addr + PMD_SIZE <= end) {
WARN_ON(!pmd_none(*pmd));
set_pmd(pmd, __pmd(__pa_nodebug(kasan_zero_pte)
- | __PAGE_KERNEL_RO));
+ | _KERNPG_TABLE));
addr += PMD_SIZE;
pmd = pmd_offset(pud, addr);
}
@@ -111,7 +111,7 @@ static int __init zero_pud_populate(pgd_t *pgd, unsigned long addr,
while (IS_ALIGNED(addr, PUD_SIZE) && addr + PUD_SIZE <= end) {
WARN_ON(!pud_none(*pud));
set_pud(pud, __pud(__pa_nodebug(kasan_zero_pmd)
- | __PAGE_KERNEL_RO));
+ | _KERNPG_TABLE));
addr += PUD_SIZE;
pud = pud_offset(pgd, addr);
}
@@ -136,7 +136,7 @@ static int __init zero_pgd_populate(unsigned long addr, unsigned long end)
while (IS_ALIGNED(addr, PGDIR_SIZE) && addr + PGDIR_SIZE <= end) {
WARN_ON(!pgd_none(*pgd));
set_pgd(pgd, __pgd(__pa_nodebug(kasan_zero_pud)
- | __PAGE_KERNEL_RO));
+ | _KERNPG_TABLE));
addr += PGDIR_SIZE;
pgd = pgd_offset_k(addr);
}
--
2.4.2


2015-06-19 12:06:18

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On Fri, Jun 19, 2015 at 02:49:19PM +0300, Andrey Ryabinin wrote:
> I guess that AMD cpus is more strict (unlike Intel) about violation
> of reserved/unused bits in page table entries. Please, try with this
> patch.

With that the guest boots.

How do I check whether KASan actually works? I don't see any note in
dmesg or some file named "*kasan*" in sysfs...

Thanks.

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--

2015-06-19 13:36:29

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On 06/19/2015 03:06 PM, Borislav Petkov wrote:
> On Fri, Jun 19, 2015 at 02:49:19PM +0300, Andrey Ryabinin wrote:
>> I guess that AMD cpus is more strict (unlike Intel) about violation
>> of reserved/unused bits in page table entries. Please, try with this
>> patch.
>
> With that the guest boots.
>

Great! Thanks.

> How do I check whether KASan actually works? I don't see any note in
> dmesg or some file named "*kasan*" in sysfs...
>

kasan will print report in dmesg whant it will find anything.

To make sure that it works you could try to load testing module (CONFIG_TEST_KASAN).
This module has bugs that kasan should catch.
Also 'slub_debug=U' in bootcmdline will improve reports and out-of-bounds accesses detection.

> Thanks.
>

2015-06-19 14:01:12

by Ingo Molnar

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables


* Andrey Ryabinin <[email protected]> wrote:

> On 06/19/2015 03:06 PM, Borislav Petkov wrote:
> > On Fri, Jun 19, 2015 at 02:49:19PM +0300, Andrey Ryabinin wrote:
> >> I guess that AMD cpus is more strict (unlike Intel) about violation
> >> of reserved/unused bits in page table entries. Please, try with this
> >> patch.
> >
> > With that the guest boots.
> >
>
> Great! Thanks.
>
> > How do I check whether KASan actually works? I don't see any note in
> > dmesg or some file named "*kasan*" in sysfs...
> >
>
> kasan will print report in dmesg whant it will find anything.

It should also printk a one line message at bootup, so that people can be sure
they are running a KASan-enabled kernel.

> To make sure that it works you could try to load testing module (CONFIG_TEST_KASAN).
> This module has bugs that kasan should catch.

That's a way too obscure mechanism just to determine whether the right kernel
config was booted. Please add a printk(), ok?

Thanks,

Ingo

2015-06-19 14:06:37

by Borislav Petkov

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On Fri, Jun 19, 2015 at 04:00:51PM +0200, Ingo Molnar wrote:
> It should also printk a one line message at bootup, so that people can
> be sure they are running a KASan-enabled kernel.

Yeah, especially if it slows down teh kernel by orders of magnitude.

In any case, here's what it says in the guest:

[ 117.061393] kasan test: kmalloc_oob_right out-of-bounds to right
[ 117.067973] ==================================================================
[ 117.071656] BUG: KASan: out of bounds access in kmalloc_oob_right+0x65/0x75 [test_kasan] at addr ffff88006816915b
[ 117.071656] Write of size 1 by task insmod/3942
[ 117.071656] =============================================================================
[ 117.071656] BUG kmalloc-128 (Not tainted): kasan: bad access detected
[ 117.071656] -----------------------------------------------------------------------------
[ 117.071656]
[ 117.071656] Disabling lock debugging due to kernel taint
[ 117.071656] INFO: Allocated in kmalloc_oob_right+0x3d/0x75 [test_kasan] age=5 cpu=1 pid=3942
[ 117.071656] __slab_alloc.isra.60.constprop.62+0x4c4/0x5e0
[ 117.071656] kmem_cache_alloc_trace+0x167/0x330
[ 117.071656] kmalloc_oob_right+0x3d/0x75 [test_kasan]
[ 117.071656] kmalloc_tests_init+0x9/0x51 [test_kasan]
[ 117.071656] do_one_initcall+0xb1/0x220
[ 117.071656] do_init_module+0xf7/0x2f8
[ 117.071656] load_module+0x2fe7/0x3e00
[ 117.071656] SyS_init_module+0x10d/0x120
[ 117.071656] system_call_fastpath+0x16/0x73
[ 117.071656] INFO: Freed in rcu_process_callbacks+0x3d3/0xd90 age=1511 cpu=6 pid=0
[ 117.071656] __slab_free+0x433/0x610
[ 117.071656] kfree+0x279/0x380
[ 117.071656] rcu_process_callbacks+0x3d3/0xd90
[ 117.071656] __do_softirq+0x154/0x7b0
[ 117.071656] irq_exit+0xba/0xe0
[ 117.071656] smp_apic_timer_interrupt+0x6a/0x80
[ 117.071656] apic_timer_interrupt+0x6d/0x80
[ 117.071656] arch_cpu_idle+0xf/0x20
[ 117.071656] cpu_startup_entry+0x5f1/0x7a0
[ 117.071656] start_secondary+0x21d/0x230
[ 117.071656] INFO: Slab 0xffffea0001a05a00 objects=37 used=31 fp=0xffff880068169290 flags=0x4000000000004080
[ 117.071656] INFO: Object 0xffff8800681690e0 @offset=4320 fp=0xffff88006816a880
[ 117.071656]
[ 117.071656] Bytes b4 ffff8800681690d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 117.071656] Object ffff8800681690e0: 80 a8 16 68 00 88 ff ff ff ff ff ff 00 00 00 00 ...h............
[ 117.071656] Object ffff8800681690f0: ff ff ff ff ff ff ff ff c0 f2 01 83 ff ff ff ff ................
[ 117.071656] Object ffff880068169100: 60 91 87 82 ff ff ff ff 00 00 00 00 00 00 00 00 `...............
[ 117.071656] Object ffff880068169110: 05 0a c4 81 ff ff ff ff 06 00 00 00 1c 00 1b 00 ................
[ 117.071656] Object ffff880068169120: 74 d6 0d 81 ff ff ff ff 28 91 16 68 00 88 ff ff t.......(..h....
[ 117.071656] Object ffff880068169130: 28 91 16 68 00 88 ff ff 00 00 00 00 00 00 00 00 (..h............
[ 117.071656] Object ffff880068169140: 00 00 00 00 00 00 00 00 60 00 00 00 00 00 00 00 ........`.......
[ 117.071656] Object ffff880068169150: 00 00 00 00 40 00 38 00 07 00 40 00 18 00 17 00 [email protected]...@.....
[ 117.071656] CPU: 1 PID: 3942 Comm: insmod Tainted: G B 4.1.0-rc8+ #3
[ 117.071656] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
[ 117.071656] 0000000000000001 ffff880061c77a28 ffffffff819af359 00000000000001b0
[ 117.071656] ffff88006ac07800 ffff880061c77a58 ffffffff8121280d ffff88006ac07800
[ 117.071656] ffffea0001a05a00 ffff8800681690e0 ffffffffa0008765 ffff880061c77a88
[ 117.071656] Call Trace:
[ 117.071656] [<ffffffff819af359>] dump_stack+0x4f/0x7b
[ 117.071656] [<ffffffff8121280d>] print_trailer+0xfd/0x160
[ 117.071656] [<ffffffffa0008765>] ? kmem_cache_oob+0xbc/0xbc [test_kasan]
[ 117.071656] [<ffffffff81218501>] object_err+0x41/0x50
[ 117.071656] [<ffffffff8121a4b8>] kasan_report_error+0x1e8/0x410
[ 117.071656] [<ffffffffa0008765>] ? kmem_cache_oob+0xbc/0xbc [test_kasan]
[ 117.071656] [<ffffffff8121ab90>] kasan_report+0x40/0x50
[ 117.071656] [<ffffffffa0008111>] ? kmalloc_oob_right+0x65/0x75 [test_kasan]
[ 117.071656] [<ffffffff81219c54>] __asan_store1+0x54/0x80
[ 117.071656] [<ffffffffa0008765>] ? kmem_cache_oob+0xbc/0xbc [test_kasan]
[ 117.071656] [<ffffffffa0008111>] kmalloc_oob_right+0x65/0x75 [test_kasan]
[ 117.071656] [<ffffffffa000876e>] kmalloc_tests_init+0x9/0x51 [test_kasan]
[ 117.071656] [<ffffffff81000301>] do_one_initcall+0xb1/0x220
[ 117.071656] [<ffffffff81219d19>] ? kasan_kmalloc+0x49/0x50
[ 117.071656] [<ffffffff812170f6>] ? kmem_cache_alloc_trace+0x106/0x330
[ 117.071656] [<ffffffff819ae865>] ? do_init_module+0x3b/0x2f8
[ 117.071656] [<ffffffff819ae921>] do_init_module+0xf7/0x2f8
[ 117.071656] [<ffffffff8114aa37>] load_module+0x2fe7/0x3e00
[ 117.071656] [<ffffffff811454d0>] ? store_uevent+0x50/0x50
[ 117.071656] [<ffffffff8114b95d>] SyS_init_module+0x10d/0x120
[ 117.071656] [<ffffffff819ba31b>] system_call_fastpath+0x16/0x73
[ 117.071656] Memory state around the buggy address:
[ 117.071656] ffff880068169000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 117.071656] ffff880068169080: fc fc fc fc fc fc fc fc fc fc fc fc 00 00 00 00
[ 117.071656] >ffff880068169100: 00 00 00 00 00 00 00 00 00 00 00 03 fc fc fc fc
[ 117.071656] ^
[ 117.071656] ffff880068169180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 117.071656] ffff880068169200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 117.071656] ==================================================================
...

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--

2015-06-19 14:16:57

by Andrey Ryabinin

[permalink] [raw]
Subject: Re: [PATCH v6 1/1] x86_64: fix KASan shadow region page tables

On 06/19/2015 05:00 PM, Ingo Molnar wrote:
>
> That's a way too obscure mechanism just to determine whether the right kernel
> config was booted. Please add a printk(), ok?
>

Sure, will do.