diff options
Diffstat (limited to 'mm/kasan/kasan.c')
-rw-r--r-- | mm/kasan/kasan.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c index 799c52b9826c..78fee632a7ee 100644 --- a/mm/kasan/kasan.c +++ b/mm/kasan/kasan.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/memblock.h> | 22 | #include <linux/memblock.h> |
23 | #include <linux/memory.h> | 23 | #include <linux/memory.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | #include <linux/module.h> | ||
25 | #include <linux/printk.h> | 26 | #include <linux/printk.h> |
26 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
@@ -395,6 +396,57 @@ void kasan_kfree_large(const void *ptr) | |||
395 | KASAN_FREE_PAGE); | 396 | KASAN_FREE_PAGE); |
396 | } | 397 | } |
397 | 398 | ||
399 | int kasan_module_alloc(void *addr, size_t size) | ||
400 | { | ||
401 | void *ret; | ||
402 | size_t shadow_size; | ||
403 | unsigned long shadow_start; | ||
404 | |||
405 | shadow_start = (unsigned long)kasan_mem_to_shadow(addr); | ||
406 | shadow_size = round_up(size >> KASAN_SHADOW_SCALE_SHIFT, | ||
407 | PAGE_SIZE); | ||
408 | |||
409 | if (WARN_ON(!PAGE_ALIGNED(shadow_start))) | ||
410 | return -EINVAL; | ||
411 | |||
412 | ret = __vmalloc_node_range(shadow_size, 1, shadow_start, | ||
413 | shadow_start + shadow_size, | ||
414 | GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, | ||
415 | PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE, | ||
416 | __builtin_return_address(0)); | ||
417 | return ret ? 0 : -ENOMEM; | ||
418 | } | ||
419 | |||
420 | void kasan_module_free(void *addr) | ||
421 | { | ||
422 | vfree(kasan_mem_to_shadow(addr)); | ||
423 | } | ||
424 | |||
425 | static void register_global(struct kasan_global *global) | ||
426 | { | ||
427 | size_t aligned_size = round_up(global->size, KASAN_SHADOW_SCALE_SIZE); | ||
428 | |||
429 | kasan_unpoison_shadow(global->beg, global->size); | ||
430 | |||
431 | kasan_poison_shadow(global->beg + aligned_size, | ||
432 | global->size_with_redzone - aligned_size, | ||
433 | KASAN_GLOBAL_REDZONE); | ||
434 | } | ||
435 | |||
436 | void __asan_register_globals(struct kasan_global *globals, size_t size) | ||
437 | { | ||
438 | int i; | ||
439 | |||
440 | for (i = 0; i < size; i++) | ||
441 | register_global(&globals[i]); | ||
442 | } | ||
443 | EXPORT_SYMBOL(__asan_register_globals); | ||
444 | |||
445 | void __asan_unregister_globals(struct kasan_global *globals, size_t size) | ||
446 | { | ||
447 | } | ||
448 | EXPORT_SYMBOL(__asan_unregister_globals); | ||
449 | |||
398 | #define DEFINE_ASAN_LOAD_STORE(size) \ | 450 | #define DEFINE_ASAN_LOAD_STORE(size) \ |
399 | void __asan_load##size(unsigned long addr) \ | 451 | void __asan_load##size(unsigned long addr) \ |
400 | { \ | 452 | { \ |