From: Zheng Yejian zhengyejian1@huawei.com
Offering: HULK hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4WBFN
--------------------------------
Refer to following procedure: klp_init_object klp_init_object_loaded klp_find_object_symbol <-- 1. oops happened when old_name is NULL!!! klp_init_func <-- 2. currently old_name is first time check here
This problem was introduced in commit 7834e94cd8b7 ("livepatch/arm64: Fix func size less than limit") which exchange order of 'klp_init_func' and 'klp_init_object_loaded' then cause old_name being used before check.
We move these checks before 'klp_init_object_loaded' and add several logs to tell why check failed.
Fixes: 7834e94cd8b7 ("livepatch/arm64: Fix func size less than limit") Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- kernel/livepatch/core.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 2da8b922278a..d34b68614f2c 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -953,19 +953,6 @@ static int klp_init_func(struct klp_object *obj, struct klp_func *func) int ret; #endif
- if (!func->old_name) - return -EINVAL; - - /* - * NOPs get the address later. The patched module must be loaded, - * see klp_init_object_loaded(). - */ - if (!func->new_func && !func->nop) - return -EINVAL; - - if (strlen(func->old_name) >= KSYM_NAME_LEN) - return -EINVAL; - INIT_LIST_HEAD(&func->stack_node); func->patched = false;
@@ -1082,6 +1069,24 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj)
if (klp_is_module(obj) && strlen(obj->name) >= MODULE_NAME_LEN) return -EINVAL; + klp_for_each_func(obj, func) { + if (!func->old_name) { + pr_err("old name is invalid\n"); + return -EINVAL; + } + /* + * NOPs get the address later. The patched module must be loaded, + * see klp_init_object_loaded(). + */ + if (!func->new_func && !func->nop) { + pr_err("new_func is invalid\n"); + return -EINVAL; + } + if (strlen(func->old_name) >= KSYM_NAME_LEN) { + pr_err("function old name is too long\n"); + return -EINVAL; + } + }
obj->patched = false; obj->mod = NULL;