From: Li Huafei lihuafei1@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6NVPT
--------------------------------
When klp_mem_prepare() fails, the requested resources are not cleared. We'd better clean up each newly requested resource upon error return.
Signed-off-by: Li Huafei lihuafei1@huawei.com Reviewed-by: Xu Kuohai xukuohai@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Signed-off-by: Zheng Yejian zhengyejian1@huawei.com Reviewed-by: Xu Kuohai xukuohai@huawei.com Signed-off-by: Jialin Zhang zhangjialin11@huawei.com --- kernel/livepatch/core.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 87ed93df7a98..4d79543d9155 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -1408,33 +1408,34 @@ static void func_node_free(struct klp_func *func) } }
-static int klp_mem_prepare(struct klp_patch *patch) +static void klp_mem_recycle(struct klp_patch *patch) { struct klp_object *obj; struct klp_func *func;
klp_for_each_object(patch, obj) { klp_for_each_func(obj, func) { - func->func_node = func_node_alloc(func); - if (func->func_node == NULL) { - pr_err("alloc func_node failed\n"); - return -ENOMEM; - } + func_node_free(func); } } - return 0; }
-static void klp_mem_recycle(struct klp_patch *patch) +static int klp_mem_prepare(struct klp_patch *patch) { struct klp_object *obj; struct klp_func *func;
klp_for_each_object(patch, obj) { klp_for_each_func(obj, func) { - func_node_free(func); + func->func_node = func_node_alloc(func); + if (func->func_node == NULL) { + klp_mem_recycle(patch); + pr_err("alloc func_node failed\n"); + return -ENOMEM; + } } } + return 0; }
static int __klp_disable_patch(struct klp_patch *patch) @@ -1697,8 +1698,11 @@ static int __klp_enable_patch(struct klp_patch *patch)
arch_klp_code_modify_prepare(); ret = klp_mem_prepare(patch); - if (ret == 0) - ret = stop_machine(klp_try_enable_patch, &patch_data, cpu_online_mask); + if (ret) { + arch_klp_code_modify_post_process(); + return ret; + } + ret = stop_machine(klp_try_enable_patch, &patch_data, cpu_online_mask); arch_klp_code_modify_post_process(); if (ret) { klp_mem_recycle(patch);