aboutsummaryrefslogtreecommitdiffstats
path: root/mm/mempool.c
diff options
context:
space:
mode:
authorAndrey Ryabinin <a.ryabinin@samsung.com>2015-04-15 19:15:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-15 19:35:20 -0400
commit923936157b158f36bd6a3d86496dce82b1a957de (patch)
tree4a78fc384c220efad52d250b49795b535fbc2db0 /mm/mempool.c
parentbda6d33042a486c8f7b15bf15a80fd07d4eab204 (diff)
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 <a.ryabinin@samsung.com> Tested-by: David Rientjes <rientjes@google.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Dmitry Chernenkov <drcheren@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Alexander Potapenko <glider@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/mempool.c')
-rw-r--r--mm/mempool.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/mm/mempool.c b/mm/mempool.c
index 2884d5bad77e..2cc08de8b1db 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -12,6 +12,7 @@
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/highmem.h> 14#include <linux/highmem.h>
15#include <linux/kasan.h>
15#include <linux/kmemleak.h> 16#include <linux/kmemleak.h>
16#include <linux/export.h> 17#include <linux/export.h>
17#include <linux/mempool.h> 18#include <linux/mempool.h>
@@ -101,10 +102,31 @@ static inline void poison_element(mempool_t *pool, void *element)
101} 102}
102#endif /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */ 103#endif /* CONFIG_DEBUG_SLAB || CONFIG_SLUB_DEBUG_ON */
103 104
105static void kasan_poison_element(mempool_t *pool, void *element)
106{
107 if (pool->alloc == mempool_alloc_slab)
108 kasan_slab_free(pool->pool_data, element);
109 if (pool->alloc == mempool_kmalloc)
110 kasan_kfree(element);
111 if (pool->alloc == mempool_alloc_pages)
112 kasan_free_pages(element, (unsigned long)pool->pool_data);
113}
114
115static void kasan_unpoison_element(mempool_t *pool, void *element)
116{
117 if (pool->alloc == mempool_alloc_slab)
118 kasan_slab_alloc(pool->pool_data, element);
119 if (pool->alloc == mempool_kmalloc)
120 kasan_krealloc(element, (size_t)pool->pool_data);
121 if (pool->alloc == mempool_alloc_pages)
122 kasan_alloc_pages(element, (unsigned long)pool->pool_data);
123}
124
104static void add_element(mempool_t *pool, void *element) 125static void add_element(mempool_t *pool, void *element)
105{ 126{
106 BUG_ON(pool->curr_nr >= pool->min_nr); 127 BUG_ON(pool->curr_nr >= pool->min_nr);
107 poison_element(pool, element); 128 poison_element(pool, element);
129 kasan_poison_element(pool, element);
108 pool->elements[pool->curr_nr++] = element; 130 pool->elements[pool->curr_nr++] = element;
109} 131}
110 132
@@ -114,6 +136,7 @@ static void *remove_element(mempool_t *pool)
114 136
115 BUG_ON(pool->curr_nr < 0); 137 BUG_ON(pool->curr_nr < 0);
116 check_element(pool, element); 138 check_element(pool, element);
139 kasan_unpoison_element(pool, element);
117 return element; 140 return element;
118} 141}
119 142