From: Ye Weihua yeweihua4@huawei.com
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 yeweihua4@huawei.com Reviewed-by: Jian Cheng cj.chengjian@huawei.com Signed-off-by: Yang Yingliang yangyingliang@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 31013c2effd3d..24e9d45beb553 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 <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 2c4aed29a2987..66a7c4befa0ee 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 69d0e28804a8a..09e447f324811 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;