Re: [PATCH v6 4/6] powerpc/32: Add KASAN support
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
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 >>