mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
mm/mempool.c: kasan: poison mempool elements
Mempools keep allocated objects in reserved for situations when ordinary allocation may not be possible to satisfy. These objects shouldn't be accessed before they leave the pool. This patch poison elements when get into the pool and unpoison when they leave it. This will let KASan to detect use-after-free of mempool's elements. Signed-off-by: Andrey Ryabinin <[email protected]> Tested-by: David Rientjes <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Dmitry Chernenkov <[email protected]> Cc: Dmitry Vyukov <[email protected]> Cc: Alexander Potapenko <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
bda6d33042
commit
923936157b
3 changed files with 38 additions and 0 deletions
|
|
@ -389,6 +389,19 @@ void kasan_krealloc(const void *object, size_t size)
|
|||
kasan_kmalloc(page->slab_cache, object, size);
|
||||
}
|
||||
|
||||
void kasan_kfree(void *ptr)
|
||||
{
|
||||
struct page *page;
|
||||
|
||||
page = virt_to_head_page(ptr);
|
||||
|
||||
if (unlikely(!PageSlab(page)))
|
||||
kasan_poison_shadow(ptr, PAGE_SIZE << compound_order(page),
|
||||
KASAN_FREE_PAGE);
|
||||
else
|
||||
kasan_slab_free(page->slab_cache, ptr);
|
||||
}
|
||||
|
||||
void kasan_kfree_large(const void *ptr)
|
||||
{
|
||||
struct page *page = virt_to_page(ptr);
|
||||
|
|
|
|||
23
mm/mempool.c
23
mm/mempool.c
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/kmemleak.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/mempool.h>
|
||||
|
|
@ -101,10 +102,31 @@ static inline void poison_element(mempool_t *pool, void *element)
|
|||
}
|
||||
#endif /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */
|
||||
|
||||
static void kasan_poison_element(mempool_t *pool, void *element)
|
||||
{
|
||||
if (pool->alloc == mempool_alloc_slab)
|
||||
kasan_slab_free(pool->pool_data, element);
|
||||
if (pool->alloc == mempool_kmalloc)
|
||||
kasan_kfree(element);
|
||||
if (pool->alloc == mempool_alloc_pages)
|
||||
kasan_free_pages(element, (unsigned long)pool->pool_data);
|
||||
}
|
||||
|
||||
static void kasan_unpoison_element(mempool_t *pool, void *element)
|
||||
{
|
||||
if (pool->alloc == mempool_alloc_slab)
|
||||
kasan_slab_alloc(pool->pool_data, element);
|
||||
if (pool->alloc == mempool_kmalloc)
|
||||
kasan_krealloc(element, (size_t)pool->pool_data);
|
||||
if (pool->alloc == mempool_alloc_pages)
|
||||
kasan_alloc_pages(element, (unsigned long)pool->pool_data);
|
||||
}
|
||||
|
||||
static void add_element(mempool_t *pool, void *element)
|
||||
{
|
||||
BUG_ON(pool->curr_nr >= pool->min_nr);
|
||||
poison_element(pool, element);
|
||||
kasan_poison_element(pool, element);
|
||||
pool->elements[pool->curr_nr++] = element;
|
||||
}
|
||||
|
||||
|
|
@ -114,6 +136,7 @@ static void *remove_element(mempool_t *pool)
|
|||
|
||||
BUG_ON(pool->curr_nr < 0);
|
||||
check_element(pool, element);
|
||||
kasan_unpoison_element(pool, element);
|
||||
return element;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue