From 6f61c955f869187003db9d68e6145f0c6e608f8f Mon Sep 17 00:00:00 2001 From: Ye Weihua Date: Fri, 6 Aug 2021 11:27:33 +0800 Subject: [PATCH] livepatch: Fix crash when access the global variable in hook hulk inclusion category: bugfix bugzilla: 175623 CVE: NA --------------------------- Livepatch allows users to call hook functions to perform some customized operations when insmod the .ko. During the test, it is found that in the ARM64 architecture, if accesses the global variables defined by other ko in hook functions, a crash occurs. Since relocation is performed during the livepatch insertion, instructions in the icache should be invalid. If the instructions in the icache are directly obtained, incorrect addresses may be obtained, caseing crash. Therefore, flush the icache before calling the hook functions. Signed-off-by: Ye Weihua Reviewed-by: Jian Cheng Signed-off-by: Yang Yingliang --- include/linux/moduleloader.h | 2 ++ kernel/livepatch/core.c | 1 + kernel/module.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/moduleloader.h b/include/linux/moduleloader.h index 31013c2effd3..24e9d45beb55 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -86,6 +86,8 @@ void module_arch_cleanup(struct module *mod); /* Any cleanup before freeing mod->module_init */ void module_arch_freeing_init(struct module *mod); +void flush_module_icache(const struct module *mod); + #ifdef CONFIG_KASAN #include #define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 2c4aed29a298..66a7c4befa0e 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1062,6 +1062,7 @@ static int klp_init_object_loaded(struct klp_patch *patch, } arch_klp_init_object_loaded(patch, obj); + flush_module_icache(patch->mod); module_enable_ro(patch->mod, true); mutex_unlock(&text_mutex); diff --git a/kernel/module.c b/kernel/module.c index 69d0e28804a8..09e447f32481 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3349,7 +3349,7 @@ static int check_module_license_and_versions(struct module *mod) return 0; } -static void flush_module_icache(const struct module *mod) +void flush_module_icache(const struct module *mod) { mm_segment_t old_fs; -- GitLab