On Sun, Sep 25, 2022 at 1:27 PM Feng Tang <feng.tang@xxxxxxxxx> wrote: > > > [1] https://lore.kernel.org/linux-mm/c7b316d30d90e5947eb8280f4dc78856a49298cf.1662411799.git.andreyknvl@xxxxxxxxxx/ > > I noticed this has been merged to -mm tree's 'mm-everything' branch, > so following is the patch againt that. Thanks! > > One thing I'm not very sure is, to check 'in-object' kasan's meta > size, I didn't check 'alloc_meta_offset', as from the code reading > the alloc_meta is never put inside slab object data area. Yes, this is correct. > Thanks, > Feng > > ---8<--- > > diff --git a/include/linux/kasan.h b/include/linux/kasan.h > index d811b3d7d2a1..96c9d56e5510 100644 > --- a/include/linux/kasan.h > +++ b/include/linux/kasan.h > @@ -302,7 +302,7 @@ static inline void kasan_unpoison_task_stack(struct task_struct *task) {} > > #ifdef CONFIG_KASAN_GENERIC > > -size_t kasan_metadata_size(struct kmem_cache *cache); > +size_t kasan_metadata_size(struct kmem_cache *cache, bool in_object); > slab_flags_t kasan_never_merge(void); > void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, > slab_flags_t *flags); > @@ -315,7 +315,8 @@ void kasan_record_aux_stack_noalloc(void *ptr); > #else /* CONFIG_KASAN_GENERIC */ > > /* Tag-based KASAN modes do not use per-object metadata. */ > -static inline size_t kasan_metadata_size(struct kmem_cache *cache) > +static inline size_t kasan_metadata_size(struct kmem_cache *cache, > + bool in_object) > { > return 0; > } > diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c > index d8b5590f9484..5a806f9b9466 100644 > --- a/mm/kasan/generic.c > +++ b/mm/kasan/generic.c > @@ -450,15 +450,22 @@ void kasan_init_object_meta(struct kmem_cache *cache, const void *object) > __memset(alloc_meta, 0, sizeof(*alloc_meta)); > } > > -size_t kasan_metadata_size(struct kmem_cache *cache) > +size_t kasan_metadata_size(struct kmem_cache *cache, bool in_object) > { > + struct kasan_cache *info = &cache->kasan_info ; > + > if (!kasan_requires_meta()) > return 0; > - return (cache->kasan_info.alloc_meta_offset ? > - sizeof(struct kasan_alloc_meta) : 0) + > - ((cache->kasan_info.free_meta_offset && > - cache->kasan_info.free_meta_offset != KASAN_NO_FREE_META) ? > - sizeof(struct kasan_free_meta) : 0); > + > + if (in_object) > + return (info->free_meta_offset ? > + 0 : sizeof(struct kasan_free_meta)); > + else > + return (info->alloc_meta_offset ? > + sizeof(struct kasan_alloc_meta) : 0) + > + ((info->free_meta_offset && > + info->free_meta_offset != KASAN_NO_FREE_META) ? > + sizeof(struct kasan_free_meta) : 0); > } > > static void __kasan_record_aux_stack(void *addr, bool can_alloc) > diff --git a/mm/slub.c b/mm/slub.c > index ce8310e131b3..a75c21a0da8b 100644 > --- a/mm/slub.c > +++ b/mm/slub.c > @@ -887,7 +887,7 @@ static void print_trailer(struct kmem_cache *s, struct slab *slab, u8 *p) > if (s->flags & SLAB_STORE_USER) > off += 2 * sizeof(struct track); > > - off += kasan_metadata_size(s); > + off += kasan_metadata_size(s, false); > > if (off != size_from_object(s)) > /* Beginning of the filler is the free pointer */ > @@ -1042,7 +1042,7 @@ static int check_pad_bytes(struct kmem_cache *s, struct slab *slab, u8 *p) > /* We also have user information there */ > off += 2 * sizeof(struct track); > > - off += kasan_metadata_size(s); > + off += kasan_metadata_size(s, false); > > if (size_from_object(s) == off) > return 1; Reviewed-by: Andrey Konovalov <andreyknvl@xxxxxxxxx> Thanks!