lkml.org 
[lkml]   [2020]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [PATCH v9 13/44] kasan: hide invalid free check implementation
    On Tue, Nov 10, 2020 at 11:11 PM Andrey Konovalov <andreyknvl@google.com> wrote:
    >
    > This is a preparatory commit for the upcoming addition of a new hardware
    > tag-based (MTE-based) KASAN mode.
    >
    > For software KASAN modes the check is based on the value in the shadow
    > memory. Hardware tag-based KASAN won't be using shadow, so hide the
    > implementation of the check in check_invalid_free().
    >
    > Also simplify the code for software tag-based mode.
    >
    > No functional changes for software modes.
    >
    > Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
    > Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
    > Reviewed-by: Marco Elver <elver@google.com>
    Reviewed-by: Alexander Potapenko <glider@google.com>

    > ---
    > Change-Id: I5fae9531c9fc948eb4d4e0c589744032fc5a0789
    > ---
    > mm/kasan/common.c | 19 +------------------
    > mm/kasan/generic.c | 7 +++++++
    > mm/kasan/kasan.h | 2 ++
    > mm/kasan/sw_tags.c | 9 +++++++++
    > 4 files changed, 19 insertions(+), 18 deletions(-)
    >
    > diff --git a/mm/kasan/common.c b/mm/kasan/common.c
    > index 123abfb760d4..543e6bf2168f 100644
    > --- a/mm/kasan/common.c
    > +++ b/mm/kasan/common.c
    > @@ -272,25 +272,9 @@ void * __must_check kasan_init_slab_obj(struct kmem_cache *cache,
    > return (void *)object;
    > }
    >
    > -static inline bool shadow_invalid(u8 tag, s8 shadow_byte)
    > -{
    > - if (IS_ENABLED(CONFIG_KASAN_GENERIC))
    > - return shadow_byte < 0 ||
    > - shadow_byte >= KASAN_GRANULE_SIZE;
    > -
    > - /* else CONFIG_KASAN_SW_TAGS: */
    > - if ((u8)shadow_byte == KASAN_TAG_INVALID)
    > - return true;
    > - if ((tag != KASAN_TAG_KERNEL) && (tag != (u8)shadow_byte))
    > - return true;
    > -
    > - return false;
    > -}
    > -
    > static bool __kasan_slab_free(struct kmem_cache *cache, void *object,
    > unsigned long ip, bool quarantine)
    > {
    > - s8 shadow_byte;
    > u8 tag;
    > void *tagged_object;
    > unsigned long rounded_up_size;
    > @@ -309,8 +293,7 @@ static bool __kasan_slab_free(struct kmem_cache *cache, void *object,
    > if (unlikely(cache->flags & SLAB_TYPESAFE_BY_RCU))
    > return false;
    >
    > - shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(object));
    > - if (shadow_invalid(tag, shadow_byte)) {
    > + if (check_invalid_free(tagged_object)) {
    > kasan_report_invalid_free(tagged_object, ip);
    > return true;
    > }
    > diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
    > index ec4417156943..e1af3b6c53b8 100644
    > --- a/mm/kasan/generic.c
    > +++ b/mm/kasan/generic.c
    > @@ -187,6 +187,13 @@ bool check_memory_region(unsigned long addr, size_t size, bool write,
    > return check_memory_region_inline(addr, size, write, ret_ip);
    > }
    >
    > +bool check_invalid_free(void *addr)
    > +{
    > + s8 shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(addr));
    > +
    > + return shadow_byte < 0 || shadow_byte >= KASAN_GRANULE_SIZE;
    > +}
    > +
    > void kasan_cache_shrink(struct kmem_cache *cache)
    > {
    > quarantine_remove_cache(cache);
    > diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
    > index 1865bb92d47a..3eff57e71ff5 100644
    > --- a/mm/kasan/kasan.h
    > +++ b/mm/kasan/kasan.h
    > @@ -164,6 +164,8 @@ void kasan_poison_memory(const void *address, size_t size, u8 value);
    > bool check_memory_region(unsigned long addr, size_t size, bool write,
    > unsigned long ret_ip);
    >
    > +bool check_invalid_free(void *addr);
    > +
    > void *find_first_bad_addr(void *addr, size_t size);
    > const char *get_bug_type(struct kasan_access_info *info);
    >
    > diff --git a/mm/kasan/sw_tags.c b/mm/kasan/sw_tags.c
    > index 4bdd7dbd6647..b2638c2cd58a 100644
    > --- a/mm/kasan/sw_tags.c
    > +++ b/mm/kasan/sw_tags.c
    > @@ -121,6 +121,15 @@ bool check_memory_region(unsigned long addr, size_t size, bool write,
    > return true;
    > }
    >
    > +bool check_invalid_free(void *addr)
    > +{
    > + u8 tag = get_tag(addr);
    > + u8 shadow_byte = READ_ONCE(*(u8 *)kasan_mem_to_shadow(reset_tag(addr)));
    > +
    > + return (shadow_byte == KASAN_TAG_INVALID) ||
    > + (tag != KASAN_TAG_KERNEL && tag != shadow_byte);
    > +}
    > +
    > #define DEFINE_HWASAN_LOAD_STORE(size) \
    > void __hwasan_load##size##_noabort(unsigned long addr) \
    > { \
    > --
    > 2.29.2.222.g5d2a92d10f8-goog
    >


    --
    Alexander Potapenko
    Software Engineer

    Google Germany GmbH
    Erika-Mann-Straße, 33
    80636 München

    Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
    Registergericht und -nummer: Hamburg, HRB 86891
    Sitz der Gesellschaft: Hamburg

    \
     
     \ /
      Last update: 2020-11-11 15:24    [W:4.443 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site