|
@@ -22,6 +22,7 @@
|
|
|
#include <linux/memblock.h>
|
|
|
#include <linux/memory.h>
|
|
|
#include <linux/mm.h>
|
|
|
+#include <linux/module.h>
|
|
|
#include <linux/printk.h>
|
|
|
#include <linux/sched.h>
|
|
|
#include <linux/slab.h>
|
|
@@ -395,6 +396,57 @@ void kasan_kfree_large(const void *ptr)
|
|
|
KASAN_FREE_PAGE);
|
|
|
}
|
|
|
|
|
|
+int kasan_module_alloc(void *addr, size_t size)
|
|
|
+{
|
|
|
+ void *ret;
|
|
|
+ size_t shadow_size;
|
|
|
+ unsigned long shadow_start;
|
|
|
+
|
|
|
+ shadow_start = (unsigned long)kasan_mem_to_shadow(addr);
|
|
|
+ shadow_size = round_up(size >> KASAN_SHADOW_SCALE_SHIFT,
|
|
|
+ PAGE_SIZE);
|
|
|
+
|
|
|
+ if (WARN_ON(!PAGE_ALIGNED(shadow_start)))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ ret = __vmalloc_node_range(shadow_size, 1, shadow_start,
|
|
|
+ shadow_start + shadow_size,
|
|
|
+ GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
|
|
|
+ PAGE_KERNEL, VM_NO_GUARD, NUMA_NO_NODE,
|
|
|
+ __builtin_return_address(0));
|
|
|
+ return ret ? 0 : -ENOMEM;
|
|
|
+}
|
|
|
+
|
|
|
+void kasan_module_free(void *addr)
|
|
|
+{
|
|
|
+ vfree(kasan_mem_to_shadow(addr));
|
|
|
+}
|
|
|
+
|
|
|
+static void register_global(struct kasan_global *global)
|
|
|
+{
|
|
|
+ size_t aligned_size = round_up(global->size, KASAN_SHADOW_SCALE_SIZE);
|
|
|
+
|
|
|
+ kasan_unpoison_shadow(global->beg, global->size);
|
|
|
+
|
|
|
+ kasan_poison_shadow(global->beg + aligned_size,
|
|
|
+ global->size_with_redzone - aligned_size,
|
|
|
+ KASAN_GLOBAL_REDZONE);
|
|
|
+}
|
|
|
+
|
|
|
+void __asan_register_globals(struct kasan_global *globals, size_t size)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < size; i++)
|
|
|
+ register_global(&globals[i]);
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__asan_register_globals);
|
|
|
+
|
|
|
+void __asan_unregister_globals(struct kasan_global *globals, size_t size)
|
|
|
+{
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(__asan_unregister_globals);
|
|
|
+
|
|
|
#define DEFINE_ASAN_LOAD_STORE(size) \
|
|
|
void __asan_load##size(unsigned long addr) \
|
|
|
{ \
|