From: Ye Weihua yeweihua4@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I4IH1G 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 yeweihua4@huawei.com Reviewed-by: Jian Cheng cj.chengjian@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com
Signed-off-by: Ye Weihua yeweihua4@huawei.com Reviewed-by: Yang Jihong yangjihong1@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- 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 4fa67a8b2265..2d835b7dc918 100644 --- a/include/linux/moduleloader.h +++ b/include/linux/moduleloader.h @@ -96,6 +96,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); + #if defined(CONFIG_KASAN) && !defined(CONFIG_KASAN_VMALLOC) #include <linux/kasan.h> #define MODULE_ALIGN (PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT) diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index de077785e507..1fde6ba196a4 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1214,6 +1214,7 @@ static int klp_init_patch(struct klp_patch *patch) goto out; }
+ flush_module_icache(patch->mod); set_mod_klp_rel_state(patch->mod, MODULE_KLP_REL_DONE); module_disable_ro(patch->mod); jump_label_apply_nops(patch->mod); diff --git a/kernel/module.c b/kernel/module.c index c5af21dcb873..e7b9ecc1aa34 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3523,7 +3523,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) { /* * Flush the instruction cache, since we've played with text.