#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
+#include <linux/kasan.h>
#include <linux/moduleloader.h>
#include <linux/bug.h>
#include <asm/alternative.h>
void *module_alloc(unsigned long size)
{
+ void *p;
+
if (PAGE_ALIGN(size) > MODULES_LEN)
return NULL;
- return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- GFP_KERNEL, PAGE_KERNEL_EXEC,
- 0, NUMA_NO_NODE,
- __builtin_return_address(0));
+ p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
+ GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
+ __builtin_return_address(0));
+ if (p && (kasan_module_alloc(p, size) < 0)) {
+ vfree(p);
+ return NULL;
+ }
+ return p;
}
void module_arch_freeing_init(struct module *mod)
memsize = min(max_physmem_end, KASAN_SHADOW_START);
shadow_alloc_size = memsize >> KASAN_SHADOW_SCALE_SHIFT;
- if (IS_ENABLED(CONFIG_MODULES))
- shadow_alloc_size += MODULES_LEN >> KASAN_SHADOW_SCALE_SHIFT;
pgalloc_low = round_up((unsigned long)_end, _SEGMENT_SIZE);
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD)) {
initrd_end =
* +- shadow end -+ | mapping |
* | ... gap ... |\ | (untracked) |
* +- modules vaddr -+ \ +----------------+
- * | 2Gb | \| 256Mb |
+ * | 2Gb | \| unmapped | allocated per module
* +-----------------+ +- shadow end ---+
*/
/* populate identity mapping */
kasan_early_vmemmap_populate(0, memsize, POPULATE_ONE2ONE);
- /* populate kasan shadow (for identity mapping / modules / zero page) */
+ /* populate kasan shadow (for identity mapping and zero page mapping) */
kasan_early_vmemmap_populate(__sha(0), __sha(memsize), POPULATE_MAP);
- if (IS_ENABLED(CONFIG_MODULES)) {
+ if (IS_ENABLED(CONFIG_MODULES))
untracked_mem_end = vmax - MODULES_LEN;
- kasan_early_vmemmap_populate(__sha(untracked_mem_end),
- __sha(vmax), POPULATE_MAP);
- }
kasan_early_vmemmap_populate(__sha(memsize), __sha(untracked_mem_end),
POPULATE_ZERO_SHADOW);
kasan_set_pgd(early_pg_dir, asce_type);