Message ID | 20190215000441.14323-3-dja@axtens.net (mailing list archive) |
---|---|
State | RFC |
Headers | show |
Series | powerpc: KASAN for 64-bit Book3E | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/apply_patch | success | next/apply_patch Successfully applied |
snowpatch_ozlabs/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 79 lines checked |
On Fri, Feb 15, 2019 at 1:05 AM Daniel Axtens <dja@axtens.net> wrote: > > Currently, shadow addresses are always addr >> shift + offset. > However, for powerpc, the virtual address space is fragmented in > ways that make this simple scheme impractical. > > Allow architectures to override: > - kasan_shadow_to_mem > - kasan_mem_to_shadow > - addr_has_shadow > > Rename addr_has_shadow to kasan_addr_has_shadow as if it is > overridden it will be available in more places, increasing the > risk of collisions. > > If architectures do not #define their own versions, the generic > code will continue to run as usual. > > Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Dmitry Vyukov <dvyukov@google.com> > --- > include/linux/kasan.h | 2 ++ > mm/kasan/generic.c | 2 +- > mm/kasan/generic_report.c | 2 +- > mm/kasan/kasan.h | 6 +++++- > mm/kasan/report.c | 6 +++--- > mm/kasan/tags.c | 2 +- > 6 files changed, 13 insertions(+), 7 deletions(-) > > diff --git a/include/linux/kasan.h b/include/linux/kasan.h > index b40ea104dd36..f6261840f94c 100644 > --- a/include/linux/kasan.h > +++ b/include/linux/kasan.h > @@ -23,11 +23,13 @@ extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; > int kasan_populate_early_shadow(const void *shadow_start, > const void *shadow_end); > > +#ifndef kasan_mem_to_shadow > static inline void *kasan_mem_to_shadow(const void *addr) > { > return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) > + KASAN_SHADOW_OFFSET; > } > +#endif > > /* Enable reporting bugs after kasan_disable_current() */ > extern void kasan_enable_current(void); > diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c > index ffc64a9a97a5..bafa2f986660 100644 > --- a/mm/kasan/generic.c > +++ b/mm/kasan/generic.c > @@ -173,7 +173,7 @@ static __always_inline void check_memory_region_inline(unsigned long addr, > if (unlikely(size == 0)) > return; > > - if (unlikely(!addr_has_shadow((void *)addr))) { > + if (unlikely(!kasan_addr_has_shadow((void *)addr))) { > kasan_report(addr, size, write, ret_ip); > return; > } > diff --git a/mm/kasan/generic_report.c b/mm/kasan/generic_report.c > index 5e12035888f2..854f4de1fe10 100644 > --- a/mm/kasan/generic_report.c > +++ b/mm/kasan/generic_report.c > @@ -110,7 +110,7 @@ static const char *get_wild_bug_type(struct kasan_access_info *info) > > const char *get_bug_type(struct kasan_access_info *info) > { > - if (addr_has_shadow(info->access_addr)) > + if (kasan_addr_has_shadow(info->access_addr)) > return get_shadow_bug_type(info); > return get_wild_bug_type(info); > } > diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h > index ea51b2d898ec..57ec24cf7bd1 100644 > --- a/mm/kasan/kasan.h > +++ b/mm/kasan/kasan.h > @@ -111,16 +111,20 @@ struct kasan_alloc_meta *get_alloc_info(struct kmem_cache *cache, > struct kasan_free_meta *get_free_info(struct kmem_cache *cache, > const void *object); > > +#ifndef kasan_shadow_to_mem > static inline const void *kasan_shadow_to_mem(const void *shadow_addr) > { > return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET) > << KASAN_SHADOW_SCALE_SHIFT); > } > +#endif > > -static inline bool addr_has_shadow(const void *addr) > +#ifndef kasan_addr_has_shadow > +static inline bool kasan_addr_has_shadow(const void *addr) > { > return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START)); > } > +#endif > > void kasan_poison_shadow(const void *address, size_t size, u8 value); > > diff --git a/mm/kasan/report.c b/mm/kasan/report.c > index ca9418fe9232..bc3355ee2dd0 100644 > --- a/mm/kasan/report.c > +++ b/mm/kasan/report.c > @@ -298,7 +298,7 @@ void kasan_report(unsigned long addr, size_t size, > untagged_addr = reset_tag(tagged_addr); > > info.access_addr = tagged_addr; > - if (addr_has_shadow(untagged_addr)) > + if (kasan_addr_has_shadow(untagged_addr)) > info.first_bad_addr = find_first_bad_addr(tagged_addr, size); > else > info.first_bad_addr = untagged_addr; > @@ -309,11 +309,11 @@ void kasan_report(unsigned long addr, size_t size, > start_report(&flags); > > print_error_description(&info); > - if (addr_has_shadow(untagged_addr)) > + if (kasan_addr_has_shadow(untagged_addr)) > print_tags(get_tag(tagged_addr), info.first_bad_addr); > pr_err("\n"); > > - if (addr_has_shadow(untagged_addr)) { > + if (kasan_addr_has_shadow(untagged_addr)) { > print_address_description(untagged_addr); > pr_err("\n"); > print_shadow_for_address(info.first_bad_addr); > diff --git a/mm/kasan/tags.c b/mm/kasan/tags.c > index bc759f8f1c67..cdefd0fe1f5d 100644 > --- a/mm/kasan/tags.c > +++ b/mm/kasan/tags.c > @@ -109,7 +109,7 @@ void check_memory_region(unsigned long addr, size_t size, bool write, > return; > > untagged_addr = reset_tag((const void *)addr); > - if (unlikely(!addr_has_shadow(untagged_addr))) { > + if (unlikely(!kasan_addr_has_shadow(untagged_addr))) { > kasan_report(addr, size, write, ret_ip); > return; > } > -- > 2.19.1 > > -- > You received this message because you are subscribed to the Google Groups "kasan-dev" group. > To unsubscribe from this group and stop receiving emails from it, send an email to kasan-dev+unsubscribe@googlegroups.com. > To post to this group, send email to kasan-dev@googlegroups.com. > To view this discussion on the web visit https://groups.google.com/d/msgid/kasan-dev/20190215000441.14323-3-dja%40axtens.net. > For more options, visit https://groups.google.com/d/optout.
diff --git a/include/linux/kasan.h b/include/linux/kasan.h index b40ea104dd36..f6261840f94c 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -23,11 +23,13 @@ extern p4d_t kasan_early_shadow_p4d[MAX_PTRS_PER_P4D]; int kasan_populate_early_shadow(const void *shadow_start, const void *shadow_end); +#ifndef kasan_mem_to_shadow static inline void *kasan_mem_to_shadow(const void *addr) { return (void *)((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET; } +#endif /* Enable reporting bugs after kasan_disable_current() */ extern void kasan_enable_current(void); diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c index ffc64a9a97a5..bafa2f986660 100644 --- a/mm/kasan/generic.c +++ b/mm/kasan/generic.c @@ -173,7 +173,7 @@ static __always_inline void check_memory_region_inline(unsigned long addr, if (unlikely(size == 0)) return; - if (unlikely(!addr_has_shadow((void *)addr))) { + if (unlikely(!kasan_addr_has_shadow((void *)addr))) { kasan_report(addr, size, write, ret_ip); return; } diff --git a/mm/kasan/generic_report.c b/mm/kasan/generic_report.c index 5e12035888f2..854f4de1fe10 100644 --- a/mm/kasan/generic_report.c +++ b/mm/kasan/generic_report.c @@ -110,7 +110,7 @@ static const char *get_wild_bug_type(struct kasan_access_info *info) const char *get_bug_type(struct kasan_access_info *info) { - if (addr_has_shadow(info->access_addr)) + if (kasan_addr_has_shadow(info->access_addr)) return get_shadow_bug_type(info); return get_wild_bug_type(info); } diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index ea51b2d898ec..57ec24cf7bd1 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -111,16 +111,20 @@ struct kasan_alloc_meta *get_alloc_info(struct kmem_cache *cache, struct kasan_free_meta *get_free_info(struct kmem_cache *cache, const void *object); +#ifndef kasan_shadow_to_mem static inline const void *kasan_shadow_to_mem(const void *shadow_addr) { return (void *)(((unsigned long)shadow_addr - KASAN_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT); } +#endif -static inline bool addr_has_shadow(const void *addr) +#ifndef kasan_addr_has_shadow +static inline bool kasan_addr_has_shadow(const void *addr) { return (addr >= kasan_shadow_to_mem((void *)KASAN_SHADOW_START)); } +#endif void kasan_poison_shadow(const void *address, size_t size, u8 value); diff --git a/mm/kasan/report.c b/mm/kasan/report.c index ca9418fe9232..bc3355ee2dd0 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -298,7 +298,7 @@ void kasan_report(unsigned long addr, size_t size, untagged_addr = reset_tag(tagged_addr); info.access_addr = tagged_addr; - if (addr_has_shadow(untagged_addr)) + if (kasan_addr_has_shadow(untagged_addr)) info.first_bad_addr = find_first_bad_addr(tagged_addr, size); else info.first_bad_addr = untagged_addr; @@ -309,11 +309,11 @@ void kasan_report(unsigned long addr, size_t size, start_report(&flags); print_error_description(&info); - if (addr_has_shadow(untagged_addr)) + if (kasan_addr_has_shadow(untagged_addr)) print_tags(get_tag(tagged_addr), info.first_bad_addr); pr_err("\n"); - if (addr_has_shadow(untagged_addr)) { + if (kasan_addr_has_shadow(untagged_addr)) { print_address_description(untagged_addr); pr_err("\n"); print_shadow_for_address(info.first_bad_addr); diff --git a/mm/kasan/tags.c b/mm/kasan/tags.c index bc759f8f1c67..cdefd0fe1f5d 100644 --- a/mm/kasan/tags.c +++ b/mm/kasan/tags.c @@ -109,7 +109,7 @@ void check_memory_region(unsigned long addr, size_t size, bool write, return; untagged_addr = reset_tag((const void *)addr); - if (unlikely(!addr_has_shadow(untagged_addr))) { + if (unlikely(!kasan_addr_has_shadow(untagged_addr))) { kasan_report(addr, size, write, ret_ip); return; }
Currently, shadow addresses are always addr >> shift + offset. However, for powerpc, the virtual address space is fragmented in ways that make this simple scheme impractical. Allow architectures to override: - kasan_shadow_to_mem - kasan_mem_to_shadow - addr_has_shadow Rename addr_has_shadow to kasan_addr_has_shadow as if it is overridden it will be available in more places, increasing the risk of collisions. If architectures do not #define their own versions, the generic code will continue to run as usual. Signed-off-by: Daniel Axtens <dja@axtens.net> --- include/linux/kasan.h | 2 ++ mm/kasan/generic.c | 2 +- mm/kasan/generic_report.c | 2 +- mm/kasan/kasan.h | 6 +++++- mm/kasan/report.c | 6 +++--- mm/kasan/tags.c | 2 +- 6 files changed, 13 insertions(+), 7 deletions(-)