Re: [PATCH] kasan: add memory corruption identification for software tag-based mode

From: Dmitry Vyukov
Date: Wed May 29 2019 - 05:46:42 EST


On Wed, May 29, 2019 at 11:35 AM Walter Wu <walter-zh.wu@xxxxxxxxxxxx> wrote:
>
> > Hi Walter,
> >
> > Please describe your use case.
> > For testing context the generic KASAN works better and it does have
> > quarantine already. For prod/canary environment the quarantine may be
> > unacceptable in most cases.
> > I think we also want to use tag-based KASAN as a base for ARM MTE
> > support in near future and quarantine will be most likely unacceptable
> > for main MTE use cases. So at the very least I think this should be
> > configurable. +Catalin for this.
> >
> My patch hope the tag-based KASAN bug report make it easier for
> programmers to see memory corruption problem.
> Because now tag-based KASAN bug report always shows âinvalid-accessâ
> error, my patch can identify it whether it is use-after-free or
> out-of-bound.
>
> We can try to make our patch is feature option. Thanks your suggestion.
> Would you explain why the quarantine is unacceptable for main MTE?
> Thanks.

MTE is supposed to be used on actual production devices.
Consider that by submitting this patch you are actually reducing
amount of available memory on your next phone ;)


> > You don't change total quarantine size and charge only sizeof(struct
> > qlist_object). If I am reading this correctly, this means that
> > quarantine will have the same large overhead as with generic KASAN. We
> > will just cache much more objects there. The boot benchmarks may be
> > unrepresentative for this. Don't we need to reduce quarantine size or
> > something?
> >
> Yes, we will try to choose 2. My original idea is belong to it. So we
> will reduce quarantine size.
>
> 1). If quarantine size is the same with generic KASAN and tag-based
> KASAN, then the miss rate of use-after-free case in generic KASAN is
> larger than tag-based KASAN.
> 2). If tag-based KASAN quarantine size is smaller generic KASAN, then
> the miss rate of use-after-free case may be the same, but tag-based
> KASAN can save slab memory usage.
>
>
> >
> > > Signed-off-by: Walter Wu <walter-zh.wu@xxxxxxxxxxxx>
> > > ---
> > > include/linux/kasan.h | 20 +++++---
> > > mm/kasan/Makefile | 4 +-
> > > mm/kasan/common.c | 15 +++++-
> > > mm/kasan/generic.c | 11 -----
> > > mm/kasan/kasan.h | 45 ++++++++++++++++-
> > > mm/kasan/quarantine.c | 107 ++++++++++++++++++++++++++++++++++++++---
> > > mm/kasan/report.c | 36 +++++++++-----
> > > mm/kasan/tags.c | 64 ++++++++++++++++++++++++
> > > mm/kasan/tags_report.c | 5 +-
> > > mm/slub.c | 2 -
> > > 10 files changed, 262 insertions(+), 47 deletions(-)
> > >
> > > diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> > > index b40ea104dd36..bbb52a8bf4a9 100644
> > > --- a/include/linux/kasan.h
> > > +++ b/include/linux/kasan.h
> > > @@ -83,6 +83,9 @@ size_t kasan_metadata_size(struct kmem_cache *cache);
> > > bool kasan_save_enable_multi_shot(void);
> > > void kasan_restore_multi_shot(bool enabled);
> > >
> > > +void kasan_cache_shrink(struct kmem_cache *cache);
> > > +void kasan_cache_shutdown(struct kmem_cache *cache);
> > > +
> > > #else /* CONFIG_KASAN */
> > >
> > > static inline void kasan_unpoison_shadow(const void *address, size_t size) {}
> > > @@ -153,20 +156,14 @@ static inline void kasan_remove_zero_shadow(void *start,
> > > static inline void kasan_unpoison_slab(const void *ptr) { }
> > > static inline size_t kasan_metadata_size(struct kmem_cache *cache) { return 0; }
> > >
> > > +static inline void kasan_cache_shrink(struct kmem_cache *cache) {}
> > > +static inline void kasan_cache_shutdown(struct kmem_cache *cache) {}
> > > #endif /* CONFIG_KASAN */
> > >
> > > #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);
> > > -
> > > -#else /* CONFIG_KASAN_GENERIC */
> > > -
> > > -static inline void kasan_cache_shrink(struct kmem_cache *cache) {}
> > > -static inline void kasan_cache_shutdown(struct kmem_cache *cache) {}
> >
> > Why do we need to move these functions?
> > For generic KASAN that's required because we store the objects
> > themselves in the quarantine, but it's not the case for tag-based mode
> > with your patch...
> >
> The quarantine in tag-based KASAN includes new objects which we create.
> Those objects are the freed information. They can be shrunk by calling
> them. So we move these function into CONFIG_KASAN.

Ok, kasan_cache_shrink is to release memory during memory pressure.
But why do we need kasan_cache_shutdown? It seems that we could leave
qobjects in quarantine when the corresponding cache is destroyed. And
in fact it's useful because we still can get use-after-frees on these
objects.