Re: [PATCH v6 4/6] powerpc/32: Add KASAN support

2019-02-20 Thread Christophe Leroy




Le 19/02/2019 à 18:23, Christophe Leroy a écrit :

This patch adds KASAN support for PPC32.

The KASAN shadow area is located between the vmalloc area and the
fixmap area.

KASAN_SHADOW_OFFSET is calculated in asm/kasan.h and extracted
by Makefile prepare rule via asm-offsets.h

For modules, the shadow area is allocated at module_alloc().

Note that on book3s it will only work on the 603 because the other
ones use hash table and can therefore not share a single PTE table
covering the entire early KASAN shadow area.

Signed-off-by: Christophe Leroy 
---
  arch/powerpc/Kconfig  |   1 +
  arch/powerpc/Makefile |   7 ++
  arch/powerpc/include/asm/book3s/32/pgtable.h  |   2 +
  arch/powerpc/include/asm/highmem.h|  10 +-
  arch/powerpc/include/asm/kasan.h  |  23 
  arch/powerpc/include/asm/nohash/32/pgtable.h  |   2 +
  arch/powerpc/include/asm/setup.h  |   5 +
  arch/powerpc/kernel/Makefile  |   9 +-
  arch/powerpc/kernel/asm-offsets.c |   4 +
  arch/powerpc/kernel/head_32.S |   3 +
  arch/powerpc/kernel/head_40x.S|   3 +
  arch/powerpc/kernel/head_44x.S|   3 +
  arch/powerpc/kernel/head_8xx.S|   3 +
  arch/powerpc/kernel/head_fsl_booke.S  |   3 +
  arch/powerpc/kernel/setup-common.c|   2 +
  arch/powerpc/lib/Makefile |   8 ++
  arch/powerpc/mm/Makefile  |   1 +
  arch/powerpc/mm/kasan/Makefile|   5 +
  arch/powerpc/mm/kasan/kasan_init_32.c | 147 ++
  arch/powerpc/mm/mem.c |   4 +
  arch/powerpc/mm/ptdump/dump_linuxpagetables.c |   8 ++


@Daniel (and others), note that to apply properly, this requires my 
other patch which moves the dumping files in a arch/powerpc/mm/ptdump/ 
subdir.


Christophe


  arch/powerpc/purgatory/Makefile   |   3 +
  arch/powerpc/xmon/Makefile|   1 +
  23 files changed, 253 insertions(+), 4 deletions(-)
  create mode 100644 arch/powerpc/mm/kasan/Makefile
  create mode 100644 arch/powerpc/mm/kasan/kasan_init_32.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 08908219fba9..850b06def84f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -175,6 +175,7 @@ config PPC
select GENERIC_TIME_VSYSCALL
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+   select HAVE_ARCH_KASAN  if PPC32
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index ac033341ed55..f0738099e31e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -427,6 +427,13 @@ else
  endif
  endif
  
+ifdef CONFIG_KASAN

+prepare: kasan_prepare
+
+kasan_prepare: prepare0
+   $(eval KASAN_SHADOW_OFFSET = $(shell awk '{if ($$2 == 
"KASAN_SHADOW_OFFSET") print $$3;}' include/generated/asm-offsets.h))
+endif
+
  # Check toolchain versions:
  # - gcc-4.6 is the minimum kernel-wide version so nothing required.
  checkbin:
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 49d76adb9bc5..4543016f80ca 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -141,6 +141,8 @@ static inline bool pte_user(pte_t pte)
   */
  #ifdef CONFIG_HIGHMEM
  #define KVIRT_TOP PKMAP_BASE
+#elif defined(CONFIG_KASAN)
+#define KVIRT_TOP  KASAN_SHADOW_START
  #else
  #define KVIRT_TOP (0xfe00UL)  /* for now, could be FIXMAP_BASE ? */
  #endif
diff --git a/arch/powerpc/include/asm/highmem.h 
b/arch/powerpc/include/asm/highmem.h
index a4b65b186ec6..483b90025bef 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -28,6 +28,7 @@
  #include 
  #include 
  #include 
+#include 
  
  extern pte_t *kmap_pte;

  extern pgprot_t kmap_prot;
@@ -50,10 +51,15 @@ extern pte_t *pkmap_page_table;
  #define PKMAP_ORDER   9
  #endif
  #define LAST_PKMAP(1 << PKMAP_ORDER)
+#ifdef CONFIG_KASAN
+#define PKMAP_TOP  KASAN_SHADOW_START
+#else
+#define PKMAP_TOP  FIXADDR_START
+#endif
  #ifndef CONFIG_PPC_4K_PAGES
-#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1))
+#define PKMAP_BASE (PKMAP_TOP - PAGE_SIZE*(LAST_PKMAP + 1))
  #else
-#define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & 
PMD_MASK)
+#define PKMAP_BASE ((PKMAP_TOP - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK)
  #endif
  #define LAST_PKMAP_MASK   (LAST_PKMAP-1)
  #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
index 2efd0e42cfc9..0bc9148f5d87 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -12,4 

[PATCH v6 4/6] powerpc/32: Add KASAN support

2019-02-19 Thread Christophe Leroy
This patch adds KASAN support for PPC32.

The KASAN shadow area is located between the vmalloc area and the
fixmap area.

KASAN_SHADOW_OFFSET is calculated in asm/kasan.h and extracted
by Makefile prepare rule via asm-offsets.h

For modules, the shadow area is allocated at module_alloc().

Note that on book3s it will only work on the 603 because the other
ones use hash table and can therefore not share a single PTE table
covering the entire early KASAN shadow area.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/Kconfig  |   1 +
 arch/powerpc/Makefile |   7 ++
 arch/powerpc/include/asm/book3s/32/pgtable.h  |   2 +
 arch/powerpc/include/asm/highmem.h|  10 +-
 arch/powerpc/include/asm/kasan.h  |  23 
 arch/powerpc/include/asm/nohash/32/pgtable.h  |   2 +
 arch/powerpc/include/asm/setup.h  |   5 +
 arch/powerpc/kernel/Makefile  |   9 +-
 arch/powerpc/kernel/asm-offsets.c |   4 +
 arch/powerpc/kernel/head_32.S |   3 +
 arch/powerpc/kernel/head_40x.S|   3 +
 arch/powerpc/kernel/head_44x.S|   3 +
 arch/powerpc/kernel/head_8xx.S|   3 +
 arch/powerpc/kernel/head_fsl_booke.S  |   3 +
 arch/powerpc/kernel/setup-common.c|   2 +
 arch/powerpc/lib/Makefile |   8 ++
 arch/powerpc/mm/Makefile  |   1 +
 arch/powerpc/mm/kasan/Makefile|   5 +
 arch/powerpc/mm/kasan/kasan_init_32.c | 147 ++
 arch/powerpc/mm/mem.c |   4 +
 arch/powerpc/mm/ptdump/dump_linuxpagetables.c |   8 ++
 arch/powerpc/purgatory/Makefile   |   3 +
 arch/powerpc/xmon/Makefile|   1 +
 23 files changed, 253 insertions(+), 4 deletions(-)
 create mode 100644 arch/powerpc/mm/kasan/Makefile
 create mode 100644 arch/powerpc/mm/kasan/kasan_init_32.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 08908219fba9..850b06def84f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -175,6 +175,7 @@ config PPC
select GENERIC_TIME_VSYSCALL
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+   select HAVE_ARCH_KASAN  if PPC32
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index ac033341ed55..f0738099e31e 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -427,6 +427,13 @@ else
 endif
 endif
 
+ifdef CONFIG_KASAN
+prepare: kasan_prepare
+
+kasan_prepare: prepare0
+   $(eval KASAN_SHADOW_OFFSET = $(shell awk '{if ($$2 == 
"KASAN_SHADOW_OFFSET") print $$3;}' include/generated/asm-offsets.h))
+endif
+
 # Check toolchain versions:
 # - gcc-4.6 is the minimum kernel-wide version so nothing required.
 checkbin:
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h 
b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 49d76adb9bc5..4543016f80ca 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -141,6 +141,8 @@ static inline bool pte_user(pte_t pte)
  */
 #ifdef CONFIG_HIGHMEM
 #define KVIRT_TOP  PKMAP_BASE
+#elif defined(CONFIG_KASAN)
+#define KVIRT_TOP  KASAN_SHADOW_START
 #else
 #define KVIRT_TOP  (0xfe00UL)  /* for now, could be FIXMAP_BASE ? */
 #endif
diff --git a/arch/powerpc/include/asm/highmem.h 
b/arch/powerpc/include/asm/highmem.h
index a4b65b186ec6..483b90025bef 100644
--- a/arch/powerpc/include/asm/highmem.h
+++ b/arch/powerpc/include/asm/highmem.h
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 
 extern pte_t *kmap_pte;
 extern pgprot_t kmap_prot;
@@ -50,10 +51,15 @@ extern pte_t *pkmap_page_table;
 #define PKMAP_ORDER9
 #endif
 #define LAST_PKMAP (1 << PKMAP_ORDER)
+#ifdef CONFIG_KASAN
+#define PKMAP_TOP  KASAN_SHADOW_START
+#else
+#define PKMAP_TOP  FIXADDR_START
+#endif
 #ifndef CONFIG_PPC_4K_PAGES
-#define PKMAP_BASE (FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1))
+#define PKMAP_BASE (PKMAP_TOP - PAGE_SIZE*(LAST_PKMAP + 1))
 #else
-#define PKMAP_BASE ((FIXADDR_START - PAGE_SIZE*(LAST_PKMAP + 1)) & 
PMD_MASK)
+#define PKMAP_BASE ((PKMAP_TOP - PAGE_SIZE*(LAST_PKMAP + 1)) & PMD_MASK)
 #endif
 #define LAST_PKMAP_MASK(LAST_PKMAP-1)
 #define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
index 2efd0e42cfc9..0bc9148f5d87 100644
--- a/arch/powerpc/include/asm/kasan.h
+++ b/arch/powerpc/include/asm/kasan.h
@@ -12,4 +12,27 @@
 #define EXPORT_SYMBOL_KASAN(fn)EXPORT_SYMBOL(fn)
 #endif
 
+#ifndef __ASSEMBLY__
+
+#include 
+#include 
+
+#define KASAN_SHADOW_SCALE_SHIFT   3
+
+#define KASAN_SHADOW_OFFSET(KASAN_SHADOW_START - \
+(PAGE_OFFSET >>