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.