Le 23/05/2019 à 07:21, Daniel Axtens a écrit :
Not all arches have a specific space carved out for modules -
some, such as powerpc, just use regular vmalloc space. Therefore,
globals in these modules cannot be backed by real shadow memory.
Can you explain in more details the reason why ?
PPC32 also uses regular vmalloc space, and it has been possible to
manage globals on it, by simply implementing a module_alloc() function.
See
https://elixir.bootlin.com/linux/v5.2-rc1/source/arch/powerpc/mm/kasan/kasan_init_32.c#L135
It is also possible to easily define a different area for modules, by
replacing the call to vmalloc_exec() by a call to __vmalloc_node_range()
as done by vmalloc_exec(), but with different bounds than
VMALLOC_START/VMALLOC_END
See https://elixir.bootlin.com/linux/v5.2-rc1/source/mm/vmalloc.c#L2633
Today in PPC64 (unlike PPC32), there is already a split between VMALLOC
space and IOREMAP space. I'm sure it would be easy to split it once more
for modules.
Christophe
In order to allow arches to perform this check, add a hook.
Signed-off-by: Daniel Axtens <d...@axtens.net>
---
include/linux/kasan.h | 5 +++++
mm/kasan/generic.c | 3 +++
2 files changed, 8 insertions(+)
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index dfee2b42d799..4752749e4797 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -18,6 +18,11 @@ struct task_struct;
static inline bool kasan_arch_is_ready(void) { return true; }
#endif
+#ifndef kasan_arch_can_register_global
+static inline bool kasan_arch_can_register_global(const void * addr) {
return true; }
+#endif
+
+
#ifndef ARCH_HAS_KASAN_EARLY_SHADOW
extern unsigned char kasan_early_shadow_page[PAGE_SIZE];
extern pte_t kasan_early_shadow_pte[PTRS_PER_PTE];
diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index 0336f31bbae3..935b06f659a0 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -208,6 +208,9 @@ static void register_global(struct kasan_global *global)
{
size_t aligned_size = round_up(global->size, KASAN_SHADOW_SCALE_SIZE);
+ if (!kasan_arch_can_register_global(global->beg))
+ return;
+
kasan_unpoison_shadow(global->beg, global->size);
kasan_poison_shadow(global->beg + aligned_size,