Skip to content

Commit

Permalink
kasan: move _RET_IP_ to inline wrappers
Browse files Browse the repository at this point in the history
Generic mm functions that call KASAN annotations that might report a bug
pass _RET_IP_ to them as an argument. This allows KASAN to include the
name of the function that called the mm function in its report's header.

Now that KASAN has inline wrappers for all of its annotations, move
_RET_IP_ to those wrappers to simplify annotation call sites.

Link: https://linux-review.googlesource.com/id/I8fb3c06d49671305ee184175a39591bc26647a67
Link: https://lkml.kernel.org/r/5c1490eddf20b436b8c4eeea83fce47687d5e4a4.1610733117.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <[email protected]>
Reviewed-by: Marco Elver <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Branislav Rankov <[email protected]>
Cc: Catalin Marinas <[email protected]>
Cc: Dmitry Vyukov <[email protected]>
Cc: Evgenii Stepanov <[email protected]>
Cc: Kevin Brodsky <[email protected]>
Cc: Peter Collingbourne <[email protected]>
Cc: Vincenzo Frascino <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
xairy authored and torvalds committed Feb 24, 2021
1 parent e66e179 commit 027b37b
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 15 deletions.
20 changes: 9 additions & 11 deletions include/linux/kasan.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,19 +185,18 @@ static __always_inline void * __must_check kasan_init_slab_obj(
}

bool __kasan_slab_free(struct kmem_cache *s, void *object, unsigned long ip);
static __always_inline bool kasan_slab_free(struct kmem_cache *s, void *object,
unsigned long ip)
static __always_inline bool kasan_slab_free(struct kmem_cache *s, void *object)
{
if (kasan_enabled())
return __kasan_slab_free(s, object, ip);
return __kasan_slab_free(s, object, _RET_IP_);
return false;
}

void __kasan_slab_free_mempool(void *ptr, unsigned long ip);
static __always_inline void kasan_slab_free_mempool(void *ptr, unsigned long ip)
static __always_inline void kasan_slab_free_mempool(void *ptr)
{
if (kasan_enabled())
__kasan_slab_free_mempool(ptr, ip);
__kasan_slab_free_mempool(ptr, _RET_IP_);
}

void * __must_check __kasan_slab_alloc(struct kmem_cache *s,
Expand Down Expand Up @@ -241,10 +240,10 @@ static __always_inline void * __must_check kasan_krealloc(const void *object,
}

void __kasan_kfree_large(void *ptr, unsigned long ip);
static __always_inline void kasan_kfree_large(void *ptr, unsigned long ip)
static __always_inline void kasan_kfree_large(void *ptr)
{
if (kasan_enabled())
__kasan_kfree_large(ptr, ip);
__kasan_kfree_large(ptr, _RET_IP_);
}

bool kasan_save_enable_multi_shot(void);
Expand Down Expand Up @@ -277,12 +276,11 @@ static inline void *kasan_init_slab_obj(struct kmem_cache *cache,
{
return (void *)object;
}
static inline bool kasan_slab_free(struct kmem_cache *s, void *object,
unsigned long ip)
static inline bool kasan_slab_free(struct kmem_cache *s, void *object)
{
return false;
}
static inline void kasan_slab_free_mempool(void *ptr, unsigned long ip) {}
static inline void kasan_slab_free_mempool(void *ptr) {}
static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object,
gfp_t flags)
{
Expand All @@ -302,7 +300,7 @@ static inline void *kasan_krealloc(const void *object, size_t new_size,
{
return (void *)object;
}
static inline void kasan_kfree_large(void *ptr, unsigned long ip) {}
static inline void kasan_kfree_large(void *ptr) {}

#endif /* CONFIG_KASAN */

Expand Down
2 changes: 1 addition & 1 deletion mm/mempool.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ static inline void poison_element(mempool_t *pool, void *element)
static __always_inline void kasan_poison_element(mempool_t *pool, void *element)
{
if (pool->alloc == mempool_alloc_slab || pool->alloc == mempool_kmalloc)
kasan_slab_free_mempool(element, _RET_IP_);
kasan_slab_free_mempool(element);
else if (pool->alloc == mempool_alloc_pages)
kasan_free_pages(element, (unsigned long)pool->pool_data);
}
Expand Down
2 changes: 1 addition & 1 deletion mm/slab.c
Original file line number Diff line number Diff line change
Expand Up @@ -3420,7 +3420,7 @@ static __always_inline void __cache_free(struct kmem_cache *cachep, void *objp,
memset(objp, 0, cachep->object_size);

/* Put the object into the quarantine, don't touch it for now. */
if (kasan_slab_free(cachep, objp, _RET_IP_))
if (kasan_slab_free(cachep, objp))
return;

/* Use KCSAN to help debug racy use-after-free. */
Expand Down
4 changes: 2 additions & 2 deletions mm/slub.c
Original file line number Diff line number Diff line change
Expand Up @@ -1528,7 +1528,7 @@ static inline void *kmalloc_large_node_hook(void *ptr, size_t size, gfp_t flags)
static __always_inline void kfree_hook(void *x)
{
kmemleak_free(x);
kasan_kfree_large(x, _RET_IP_);
kasan_kfree_large(x);
}

static __always_inline bool slab_free_hook(struct kmem_cache *s, void *x)
Expand Down Expand Up @@ -1558,7 +1558,7 @@ static __always_inline bool slab_free_hook(struct kmem_cache *s, void *x)
KCSAN_ACCESS_WRITE | KCSAN_ACCESS_ASSERT);

/* KASAN might put x into memory quarantine, delaying its reuse */
return kasan_slab_free(s, x, _RET_IP_);
return kasan_slab_free(s, x);
}

static inline bool slab_free_freelist_hook(struct kmem_cache *s,
Expand Down

0 comments on commit 027b37b

Please sign in to comment.