From 58f70b7dbd2cd56a4f86cfb1a08298752c57256a Mon Sep 17 00:00:00 2001 From: Ye Weihua Date: Fri, 26 Nov 2021 16:26:49 +0800 Subject: [PATCH] livepatch: Fix crash when access the global variable in hook 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 Reviewed-by: Jian Cheng Signed-off-by: Yang Yingliang Signed-off-by: Ye Weihua Reviewed-by: Yang Jihong Signed-off-by: Zheng Zengkai --- 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 #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. -- GitLab