public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 1/1] x86_64: fix KASan shadow region page tables
@ 2015-06-02 12:57 Alexander Popov
  2015-06-03  7:44 ` Ingo Molnar
  0 siblings, 1 reply; 6+ messages in thread
From: Alexander Popov @ 2015-06-02 12:57 UTC (permalink / raw)
  To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Ryabinin,
	Andrey Konovalov, Andrew Morton, Kees Cook,
	Peter Zijlstra (Intel), Andy Lutomirski, Alexander Kuleshov,
	Borislav Petkov, Denys Vlasenko, 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 in early_idt_handler 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>
---

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.

 arch/x86/include/asm/kasan.h |  6 ++----
 arch/x86/kernel/head64.c     | 10 +++++++---
 arch/x86/kernel/head_64.S    | 29 -----------------------------
 arch/x86/mm/kasan_init_64.c  | 31 ++++++++++++++++++++++++++++++-
 4 files changed, 39 insertions(+), 37 deletions(-)

diff --git a/arch/x86/include/asm/kasan.h b/arch/x86/include/asm/kasan.h
index 8b22422..d505f76 100644
--- a/arch/x86/include/asm/kasan.h
+++ b/arch/x86/include/asm/kasan.h
@@ -14,15 +14,13 @@
 
 #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 2b55ee6..e9a84a1 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -161,11 +161,15 @@ 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();
+	kasan_map_early_shadow(early_level4_pgt);
+
 	for (i = 0; i < NUM_EXCEPTION_VECTORS; i++)
 		set_intr_gate(i, early_idt_handlers[i]);
 	load_idt((const struct desc_ptr *)&idt_descr);
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index ae6588b..b5c80c8 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -514,38 +514,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..9968732 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)
 {
@@ -166,6 +178,23 @@ 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);
+}
+
 void __init kasan_init(void)
 {
 	int i;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/1] x86_64: fix KASan shadow region page tables
  2015-06-02 12:57 [PATCH v4 1/1] x86_64: fix KASan shadow region page tables Alexander Popov
@ 2015-06-03  7:44 ` Ingo Molnar
  2015-06-03  8:37   ` Alexander Popov
  2015-06-03  8:44   ` Andrey Ryabinin
  0 siblings, 2 replies; 6+ messages in thread
From: Ingo Molnar @ 2015-06-03  7:44 UTC (permalink / raw)
  To: Alexander Popov
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Ryabinin,
	Andrey Konovalov, Andrew Morton, Kees Cook,
	Peter Zijlstra (Intel), Andy Lutomirski, Alexander Kuleshov,
	Borislav Petkov, Denys Vlasenko, x86, linux-kernel


* Alexander Popov <alpopov@ptsecurity.com> wrote:

>  #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 2b55ee6..e9a84a1 100644
> --- a/arch/x86/kernel/head64.c
> +++ b/arch/x86/kernel/head64.c
> @@ -161,11 +161,15 @@ 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();
> +	kasan_map_early_shadow(early_level4_pgt);

So why isn't kasan_map_early_shadow() called in kasan_early_init()?

High level x86 init code should not be polluted with too many low level details.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/1] x86_64: fix KASan shadow region page tables
  2015-06-03  7:44 ` Ingo Molnar
@ 2015-06-03  8:37   ` Alexander Popov
  2015-06-03  8:44   ` Andrey Ryabinin
  1 sibling, 0 replies; 6+ messages in thread
From: Alexander Popov @ 2015-06-03  8:37 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Ryabinin,
	Andrey Konovalov, Andrew Morton, Kees Cook,
	Peter Zijlstra (Intel), Andy Lutomirski, Alexander Kuleshov,
	Borislav Petkov, Denys Vlasenko, x86, linux-kernel

On 03.06.2015 10:44, Ingo Molnar wrote:
> 
> * Alexander Popov <alpopov@ptsecurity.com> wrote:
>> +	kasan_early_init();
>> +	kasan_map_early_shadow(early_level4_pgt);
> 
> So why isn't kasan_map_early_shadow() called in kasan_early_init()?
> 
> High level x86 init code should not be polluted with too many low level details.

Hello, Ingo.

kasan_map_early_shadow() is called twice in x86_64_start_kernel():
once for early_level4_pgt and then later for init_level4_pgt.

I've decided to introduce separate kasan_early_init() to avoid big changes
which can bring consequences that I don't understand.

Best regards,
Alexander

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/1] x86_64: fix KASan shadow region page tables
  2015-06-03  7:44 ` Ingo Molnar
  2015-06-03  8:37   ` Alexander Popov
@ 2015-06-03  8:44   ` Andrey Ryabinin
  2015-06-03 14:10     ` Alexander Popov
  1 sibling, 1 reply; 6+ messages in thread
From: Andrey Ryabinin @ 2015-06-03  8:44 UTC (permalink / raw)
  To: Ingo Molnar, Alexander Popov
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov,
	Andrew Morton, Kees Cook, Peter Zijlstra (Intel), Andy Lutomirski,
	Alexander Kuleshov, Borislav Petkov, Denys Vlasenko, x86,
	linux-kernel

On 06/03/2015 10:44 AM, Ingo Molnar wrote:
> 
> * Alexander Popov <alpopov@ptsecurity.com> wrote:
> 
>>  #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 2b55ee6..e9a84a1 100644
>> --- a/arch/x86/kernel/head64.c
>> +++ b/arch/x86/kernel/head64.c
>> @@ -161,11 +161,15 @@ 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();
>> +	kasan_map_early_shadow(early_level4_pgt);
> 
> So why isn't kasan_map_early_shadow() called in kasan_early_init()?
> 
> High level x86 init code should not be polluted with too many low level details.
> 

Agreed. Eventually, with the patch bellow, we could get rid of the second
kasan_map_early_shadow(init_level4_pgt) call in x86_64_start_kernel().
Make it static, and call it from kasan_early_init() only.

------------------------------------------------------
From: Andrey Ryabinin <a.ryabinin@samsung.com>
Subject: [PATCH] x86_64: remove not needed clear_page for init_level4_page

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];



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/1] x86_64: fix KASan shadow region page tables
  2015-06-03  8:44   ` Andrey Ryabinin
@ 2015-06-03 14:10     ` Alexander Popov
  2015-06-03 16:33       ` Andrey Ryabinin
  0 siblings, 1 reply; 6+ messages in thread
From: Alexander Popov @ 2015-06-03 14:10 UTC (permalink / raw)
  To: Andrey Ryabinin, Ingo Molnar
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov,
	Andrew Morton, Kees Cook, Peter Zijlstra (Intel), Andy Lutomirski,
	Alexander Kuleshov, Borislav Petkov, Denys Vlasenko, x86,
	linux-kernel

On 03.06.2015 11:44, Andrey Ryabinin wrote:
> On 06/03/2015 10:44 AM, Ingo Molnar wrote:
>>
>> * Alexander Popov <alpopov@ptsecurity.com> wrote:
>>
>>>  #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 2b55ee6..e9a84a1 100644
>>> --- a/arch/x86/kernel/head64.c
>>> +++ b/arch/x86/kernel/head64.c
>>> @@ -161,11 +161,15 @@ 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();
>>> +	kasan_map_early_shadow(early_level4_pgt);
>>
>> So why isn't kasan_map_early_shadow() called in kasan_early_init()?
>>
>> High level x86 init code should not be polluted with too many low level details.
>>
> 
> Agreed. Eventually, with the patch bellow, we could get rid of the second
> kasan_map_early_shadow(init_level4_pgt) call in x86_64_start_kernel().
> Make it static, and call it from kasan_early_init() only.
> 
> ------------------------------------------------------
> From: Andrey Ryabinin <a.ryabinin@samsung.com>
> Subject: [PATCH] x86_64: remove not needed clear_page for init_level4_page
> 
> 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];
> 

Hello Ingo and Andrey.

Should I make a "patch series" containing Andrey's patch and the 5'th version
of my patch or just include changes from Andrey's patch into mine?

Best regards,
Alexander

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/1] x86_64: fix KASan shadow region page tables
  2015-06-03 14:10     ` Alexander Popov
@ 2015-06-03 16:33       ` Andrey Ryabinin
  0 siblings, 0 replies; 6+ messages in thread
From: Andrey Ryabinin @ 2015-06-03 16:33 UTC (permalink / raw)
  To: Alexander Popov, Ingo Molnar
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrey Konovalov,
	Andrew Morton, Kees Cook, Peter Zijlstra (Intel), Andy Lutomirski,
	Alexander Kuleshov, Borislav Petkov, Denys Vlasenko, x86,
	linux-kernel

On 06/03/2015 05:10 PM, Alexander Popov wrote:
> 
> Hello Ingo and Andrey.
> 
> Should I make a "patch series" containing Andrey's patch and the 5'th version
> of my patch or just include changes from Andrey's patch into mine?
> 

These patches contain logically separate changes, so please don't fold them into one.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-06-03 16:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-06-02 12:57 [PATCH v4 1/1] x86_64: fix KASan shadow region page tables Alexander Popov
2015-06-03  7:44 ` Ingo Molnar
2015-06-03  8:37   ` Alexander Popov
2015-06-03  8:44   ` Andrey Ryabinin
2015-06-03 14:10     ` Alexander Popov
2015-06-03 16:33       ` Andrey Ryabinin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox