aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/kasan.h5
-rw-r--r--include/linux/vmalloc.h1
-rw-r--r--kernel/module.c2
-rw-r--r--mm/kasan/kasan.c14
-rw-r--r--mm/vmalloc.c1
5 files changed, 16 insertions, 7 deletions
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 72ba725ddf9c..5fa48a21d73e 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -5,6 +5,7 @@
5 5
6struct kmem_cache; 6struct kmem_cache;
7struct page; 7struct page;
8struct vm_struct;
8 9
9#ifdef CONFIG_KASAN 10#ifdef CONFIG_KASAN
10 11
@@ -52,7 +53,7 @@ void kasan_slab_free(struct kmem_cache *s, void *object);
52#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT) 53#define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
53 54
54int kasan_module_alloc(void *addr, size_t size); 55int kasan_module_alloc(void *addr, size_t size);
55void kasan_module_free(void *addr); 56void kasan_free_shadow(const struct vm_struct *vm);
56 57
57#else /* CONFIG_KASAN */ 58#else /* CONFIG_KASAN */
58 59
@@ -82,7 +83,7 @@ static inline void kasan_slab_alloc(struct kmem_cache *s, void *object) {}
82static inline void kasan_slab_free(struct kmem_cache *s, void *object) {} 83static inline void kasan_slab_free(struct kmem_cache *s, void *object) {}
83 84
84static inline int kasan_module_alloc(void *addr, size_t size) { return 0; } 85static inline int kasan_module_alloc(void *addr, size_t size) { return 0; }
85static inline void kasan_module_free(void *addr) {} 86static inline void kasan_free_shadow(const struct vm_struct *vm) {}
86 87
87#endif /* CONFIG_KASAN */ 88#endif /* CONFIG_KASAN */
88 89
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 7d7acb35603d..0ec598381f97 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -17,6 +17,7 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */
17#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */ 17#define VM_VPAGES 0x00000010 /* buffer for pages was vmalloc'ed */
18#define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ 18#define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */
19#define VM_NO_GUARD 0x00000040 /* don't add guard page */ 19#define VM_NO_GUARD 0x00000040 /* don't add guard page */
20#define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */
20/* bits [20..32] reserved for arch specific ioremap internals */ 21/* bits [20..32] reserved for arch specific ioremap internals */
21 22
22/* 23/*
diff --git a/kernel/module.c b/kernel/module.c
index cc93cf68653c..b3d634ed06c9 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -56,7 +56,6 @@
56#include <linux/async.h> 56#include <linux/async.h>
57#include <linux/percpu.h> 57#include <linux/percpu.h>
58#include <linux/kmemleak.h> 58#include <linux/kmemleak.h>
59#include <linux/kasan.h>
60#include <linux/jump_label.h> 59#include <linux/jump_label.h>
61#include <linux/pfn.h> 60#include <linux/pfn.h>
62#include <linux/bsearch.h> 61#include <linux/bsearch.h>
@@ -1814,7 +1813,6 @@ static void unset_module_init_ro_nx(struct module *mod) { }
1814void __weak module_memfree(void *module_region) 1813void __weak module_memfree(void *module_region)
1815{ 1814{
1816 vfree(module_region); 1815 vfree(module_region);
1817 kasan_module_free(module_region);
1818} 1816}
1819 1817
1820void __weak module_arch_cleanup(struct module *mod) 1818void __weak module_arch_cleanup(struct module *mod)
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index 78fee632a7ee..936d81661c47 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -29,6 +29,7 @@
29#include <linux/stacktrace.h> 29#include <linux/stacktrace.h>
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/vmalloc.h>
32#include <linux/kasan.h> 33#include <linux/kasan.h>
33 34
34#include "kasan.h" 35#include "kasan.h"
@@ -414,12 +415,19 @@ int kasan_module_alloc(void *addr, size_t size)
414 GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, 415 GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
415 PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE, 416 PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE,
416 __builtin_return_address(0)); 417 __builtin_return_address(0));
417 return ret ? 0 : -ENOMEM; 418
419 if (ret) {
420 find_vm_area(addr)->flags |= VM_KASAN;
421 return 0;
422 }
423
424 return -ENOMEM;
418} 425}
419 426
420void kasan_module_free(void *addr) 427void kasan_free_shadow(const struct vm_struct *vm)
421{ 428{
422 vfree(kasan_mem_to_shadow(addr)); 429 if (vm->flags & VM_KASAN)
430 vfree(kasan_mem_to_shadow(vm->addr));
423} 431}
424 432
425static void register_global(struct kasan_global *global) 433static void register_global(struct kasan_global *global)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 35b25e1340ca..49abccf29a29 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1418,6 +1418,7 @@ struct vm_struct *remove_vm_area(const void *addr)
1418 spin_unlock(&vmap_area_lock); 1418 spin_unlock(&vmap_area_lock);
1419 1419
1420 vmap_debug_free_range(va->va_start, va->va_end); 1420 vmap_debug_free_range(va->va_start, va->va_end);
1421 kasan_free_shadow(vm);
1421 free_unmap_vmap_area(va); 1422 free_unmap_vmap_area(va);
1422 vm->size -= PAGE_SIZE; 1423 vm->size -= PAGE_SIZE;
1423 1424