diff mbox series

[v5,12/38] kmsan: x86: sync metadata pages on page fault

Message ID 20200325161249.55095-13-glider@google.com (mailing list archive)
State New, archived
Headers show
Series Add KernelMemorySanitizer infrastructure | expand

Commit Message

Alexander Potapenko March 25, 2020, 4:12 p.m. UTC
KMSAN assumes shadow and origin pages for every allocated page are
accessible. For pages in vmalloc region those metadata pages reside in
[VMALLOC_END, VMALLOC_META_END), therefore we must sync a bigger memory
region.

Signed-off-by: Alexander Potapenko <glider@google.com>
To: Alexander Potapenko <glider@google.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Vegard Nossum <vegard.nossum@oracle.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Marco Elver <elver@google.com>
Cc: Andrey Konovalov <andreyknvl@google.com>
Cc: linux-mm@kvack.org

---

Change-Id: I0d54855489870ef1180b37fe2120b601da464bf7
---
 arch/x86/mm/fault.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Andrey Konovalov April 23, 2020, 7:15 p.m. UTC | #1
On Wed, Mar 25, 2020 at 5:13 PM <glider@google.com> wrote:
>
> KMSAN assumes shadow and origin pages for every allocated page are
> accessible. For pages in vmalloc region those metadata pages reside in
> [VMALLOC_END, VMALLOC_META_END), therefore we must sync a bigger memory
> region.
>
> Signed-off-by: Alexander Potapenko <glider@google.com>
> To: Alexander Potapenko <glider@google.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Vegard Nossum <vegard.nossum@oracle.com>
> Cc: Dmitry Vyukov <dvyukov@google.com>
> Cc: Marco Elver <elver@google.com>
> Cc: Andrey Konovalov <andreyknvl@google.com>
> Cc: linux-mm@kvack.org

Reviewed-by: Andrey Konovalov <andreyknvl@google.com>

>
> ---
>
> Change-Id: I0d54855489870ef1180b37fe2120b601da464bf7
> ---
>  arch/x86/mm/fault.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
> index a51df516b87bf..d22e373fa2124 100644
> --- a/arch/x86/mm/fault.c
> +++ b/arch/x86/mm/fault.c
> @@ -331,11 +331,21 @@ static void dump_pagetable(unsigned long address)
>
>  void vmalloc_sync_mappings(void)
>  {
> +#ifndef CONFIG_KMSAN
>         /*
>          * 64-bit mappings might allocate new p4d/pud pages
>          * that need to be propagated to all tasks' PGDs.
>          */
>         sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END);
> +#else
> +       /*
> +        * For KMSAN, make sure metadata pages for vmalloc area and modules are
> +        * also synced.
> +        */
> +       sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_META_END);
> +       sync_global_pgds(MODULES_SHADOW_START & PGDIR_MASK,
> +               MODULES_ORIGIN_END);
> +#endif
>  }
>
>  void vmalloc_sync_unmappings(void)
> @@ -360,7 +370,17 @@ static noinline int vmalloc_fault(unsigned long address)
>         pte_t *pte;
>
>         /* Make sure we are in vmalloc area: */
> +#ifdef CONFIG_KMSAN
> +       /*
> +        * For KMSAN, make sure metadata pages for vmalloc area and modules are
> +        * also synced.
> +        */
> +       if (!(address >= VMALLOC_START && address < VMALLOC_META_END) &&
> +               !(address >= MODULES_SHADOW_START &&
> +                 address < MODULES_ORIGIN_END))
> +#else
>         if (!(address >= VMALLOC_START && address < VMALLOC_END))
> +#endif
>                 return -1;
>
>         /*
> --
> 2.25.1.696.g5e7596f4ac-goog
>
diff mbox series

Patch

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index a51df516b87bf..d22e373fa2124 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -331,11 +331,21 @@  static void dump_pagetable(unsigned long address)
 
 void vmalloc_sync_mappings(void)
 {
+#ifndef CONFIG_KMSAN
 	/*
 	 * 64-bit mappings might allocate new p4d/pud pages
 	 * that need to be propagated to all tasks' PGDs.
 	 */
 	sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_END);
+#else
+	/*
+	 * For KMSAN, make sure metadata pages for vmalloc area and modules are
+	 * also synced.
+	 */
+	sync_global_pgds(VMALLOC_START & PGDIR_MASK, VMALLOC_META_END);
+	sync_global_pgds(MODULES_SHADOW_START & PGDIR_MASK,
+		MODULES_ORIGIN_END);
+#endif
 }
 
 void vmalloc_sync_unmappings(void)
@@ -360,7 +370,17 @@  static noinline int vmalloc_fault(unsigned long address)
 	pte_t *pte;
 
 	/* Make sure we are in vmalloc area: */
+#ifdef CONFIG_KMSAN
+	/*
+	 * For KMSAN, make sure metadata pages for vmalloc area and modules are
+	 * also synced.
+	 */
+	if (!(address >= VMALLOC_START && address < VMALLOC_META_END) &&
+		!(address >= MODULES_SHADOW_START &&
+		  address < MODULES_ORIGIN_END))
+#else
 	if (!(address >= VMALLOC_START && address < VMALLOC_END))
+#endif
 		return -1;
 
 	/*