Message ID | 9405f32797b52616cd0746bcea37df94e8e4256a.1541525354.git.andreyknvl@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | kasan: add software tag-based mode for arm64 | expand |
On Tue, Nov 06, 2018 at 06:30:22PM +0100, Andrey Konovalov wrote: > A tag-based KASAN shadow memory cell contains a memory tag, that > corresponds to the tag in the top byte of the pointer, that points to that > memory. The native top byte value of kernel pointers is 0xff, so with > tag-based KASAN we need to initialize shadow memory to 0xff. > > Reviewed-by: Andrey Ryabinin <aryabinin@virtuozzo.com> > Reviewed-by: Dmitry Vyukov <dvyukov@google.com> > Signed-off-by: Andrey Konovalov <andreyknvl@google.com> > --- > arch/arm64/mm/kasan_init.c | 16 ++++++++++++++-- > include/linux/kasan.h | 8 ++++++++ > mm/kasan/common.c | 3 ++- > 3 files changed, 24 insertions(+), 3 deletions(-) > > diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c > index 63527e585aac..18ebc8994a7b 100644 > --- a/arch/arm64/mm/kasan_init.c > +++ b/arch/arm64/mm/kasan_init.c > @@ -43,6 +43,15 @@ static phys_addr_t __init kasan_alloc_zeroed_page(int node) > return __pa(p); > } > > +static phys_addr_t __init kasan_alloc_raw_page(int node) > +{ > + void *p = memblock_alloc_try_nid_raw(PAGE_SIZE, PAGE_SIZE, > + __pa(MAX_DMA_ADDRESS), > + MEMBLOCK_ALLOC_ACCESSIBLE, > + node); > + return __pa(p); > +} > + > static pte_t *__init kasan_pte_offset(pmd_t *pmdp, unsigned long addr, int node, > bool early) > { > @@ -88,7 +97,9 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr, > > do { > phys_addr_t page_phys = early ? __pa_symbol(kasan_zero_page) > - : kasan_alloc_zeroed_page(node); > + : kasan_alloc_raw_page(node); > + if (!early) > + memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE); > next = addr + PAGE_SIZE; > set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL)); > } while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep))); > @@ -138,6 +149,7 @@ asmlinkage void __init kasan_early_init(void) > KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT))); > BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE)); > BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE)); > + > kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, > true); > } > @@ -234,7 +246,7 @@ void __init kasan_init(void) > set_pte(&kasan_zero_pte[i], > pfn_pte(sym_to_pfn(kasan_zero_page), PAGE_KERNEL_RO)); > > - memset(kasan_zero_page, 0, PAGE_SIZE); > + memset(kasan_zero_page, KASAN_SHADOW_INIT, PAGE_SIZE); If this isn't going to contain zero, can we please have a preparatory patch renaming this to something which isn't misleading? Perhaps kasan_common_shadow_page? Thanks, Mark.
On Wed, Nov 7, 2018 at 6:08 PM, Mark Rutland <mark.rutland@arm.com> wrote: > On Tue, Nov 06, 2018 at 06:30:22PM +0100, Andrey Konovalov wrote: >> A tag-based KASAN shadow memory cell contains a memory tag, that >> corresponds to the tag in the top byte of the pointer, that points to that >> memory. The native top byte value of kernel pointers is 0xff, so with >> tag-based KASAN we need to initialize shadow memory to 0xff. >> >> Reviewed-by: Andrey Ryabinin <aryabinin@virtuozzo.com> >> Reviewed-by: Dmitry Vyukov <dvyukov@google.com> >> Signed-off-by: Andrey Konovalov <andreyknvl@google.com> >> --- >> arch/arm64/mm/kasan_init.c | 16 ++++++++++++++-- >> include/linux/kasan.h | 8 ++++++++ >> mm/kasan/common.c | 3 ++- >> 3 files changed, 24 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c >> index 63527e585aac..18ebc8994a7b 100644 >> --- a/arch/arm64/mm/kasan_init.c >> +++ b/arch/arm64/mm/kasan_init.c >> @@ -43,6 +43,15 @@ static phys_addr_t __init kasan_alloc_zeroed_page(int node) >> return __pa(p); >> } >> >> +static phys_addr_t __init kasan_alloc_raw_page(int node) >> +{ >> + void *p = memblock_alloc_try_nid_raw(PAGE_SIZE, PAGE_SIZE, >> + __pa(MAX_DMA_ADDRESS), >> + MEMBLOCK_ALLOC_ACCESSIBLE, >> + node); >> + return __pa(p); >> +} >> + >> static pte_t *__init kasan_pte_offset(pmd_t *pmdp, unsigned long addr, int node, >> bool early) >> { >> @@ -88,7 +97,9 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr, >> >> do { >> phys_addr_t page_phys = early ? __pa_symbol(kasan_zero_page) >> - : kasan_alloc_zeroed_page(node); >> + : kasan_alloc_raw_page(node); >> + if (!early) >> + memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE); >> next = addr + PAGE_SIZE; >> set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL)); >> } while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep))); >> @@ -138,6 +149,7 @@ asmlinkage void __init kasan_early_init(void) >> KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT))); >> BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE)); >> BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE)); >> + >> kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, >> true); >> } >> @@ -234,7 +246,7 @@ void __init kasan_init(void) >> set_pte(&kasan_zero_pte[i], >> pfn_pte(sym_to_pfn(kasan_zero_page), PAGE_KERNEL_RO)); >> >> - memset(kasan_zero_page, 0, PAGE_SIZE); >> + memset(kasan_zero_page, KASAN_SHADOW_INIT, PAGE_SIZE); > > If this isn't going to contain zero, can we please have a preparatory > patch renaming this to something which isn't misleading? > > Perhaps kasan_common_shadow_page? Will rename to kasan_early_shadow_page in v11, thanks! > > Thanks, > Mark.
diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 63527e585aac..18ebc8994a7b 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -43,6 +43,15 @@ static phys_addr_t __init kasan_alloc_zeroed_page(int node) return __pa(p); } +static phys_addr_t __init kasan_alloc_raw_page(int node) +{ + void *p = memblock_alloc_try_nid_raw(PAGE_SIZE, PAGE_SIZE, + __pa(MAX_DMA_ADDRESS), + MEMBLOCK_ALLOC_ACCESSIBLE, + node); + return __pa(p); +} + static pte_t *__init kasan_pte_offset(pmd_t *pmdp, unsigned long addr, int node, bool early) { @@ -88,7 +97,9 @@ static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr, do { phys_addr_t page_phys = early ? __pa_symbol(kasan_zero_page) - : kasan_alloc_zeroed_page(node); + : kasan_alloc_raw_page(node); + if (!early) + memset(__va(page_phys), KASAN_SHADOW_INIT, PAGE_SIZE); next = addr + PAGE_SIZE; set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL)); } while (ptep++, addr = next, addr != end && pte_none(READ_ONCE(*ptep))); @@ -138,6 +149,7 @@ asmlinkage void __init kasan_early_init(void) KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT))); BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE)); BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE)); + kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, true); } @@ -234,7 +246,7 @@ void __init kasan_init(void) set_pte(&kasan_zero_pte[i], pfn_pte(sym_to_pfn(kasan_zero_page), PAGE_KERNEL_RO)); - memset(kasan_zero_page, 0, PAGE_SIZE); + memset(kasan_zero_page, KASAN_SHADOW_INIT, PAGE_SIZE); cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); /* At this point kasan is fully initialized. Enable error messages */ diff --git a/include/linux/kasan.h b/include/linux/kasan.h index b66fdf5ea7ab..7f6574c35c62 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -153,6 +153,8 @@ static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; } #ifdef CONFIG_KASAN_GENERIC +#define KASAN_SHADOW_INIT 0 + void kasan_cache_shrink(struct kmem_cache *cache); void kasan_cache_shutdown(struct kmem_cache *cache); @@ -163,4 +165,10 @@ static inline void kasan_cache_shutdown(struct kmem_cache *cache) {} #endif /* CONFIG_KASAN_GENERIC */ +#ifdef CONFIG_KASAN_SW_TAGS + +#define KASAN_SHADOW_INIT 0xFF + +#endif /* CONFIG_KASAN_SW_TAGS */ + #endif /* LINUX_KASAN_H */ diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 5f68c93734ba..7134e75447ff 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -473,11 +473,12 @@ int kasan_module_alloc(void *addr, size_t size) ret = __vmalloc_node_range(shadow_size, 1, shadow_start, shadow_start + shadow_size, - GFP_KERNEL | __GFP_ZERO, + GFP_KERNEL, PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE, __builtin_return_address(0)); if (ret) { + __memset(ret, KASAN_SHADOW_INIT, shadow_size); find_vm_area(addr)->flags |= VM_KASAN; kmemleak_ignore(ret); return 0;