diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index bb7ecc516b4a4681a07f96754d6169751c02f770..6c5b3f52967ad9f5f4edfcafdbdfbffa087c9a46 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include "core.h" #ifdef CONFIG_LIVEPATCH_FTRACE @@ -1602,18 +1603,11 @@ static int check_address_conflict(struct klp_patch *patch) { struct klp_object *obj; struct klp_func *func; - int ret; + int ret = 0; void *start; void *end; - /* - * Locks seem required as comment of jump_label_text_reserved() said: - * Caller must hold jump_label_mutex. - * But looking into implementation of jump_label_text_reserved() and - * static_call_text_reserved(), call sites of every jump_label or static_call - * are checked, and they won't be changed after corresponding module inserted, - * so no need to take jump_label_lock and static_call_lock here. - */ + jump_label_lock(); klp_for_each_object(patch, obj) { klp_for_each_func(obj, func) { start = func->old_func; @@ -1622,17 +1616,21 @@ static int check_address_conflict(struct klp_patch *patch) if (ret) { pr_err("'%s' has static key in first %zu bytes, ret=%d\n", func->old_name, KLP_MAX_REPLACE_SIZE, ret); - return -EINVAL; + ret = -EINVAL; + goto out; } ret = static_call_text_reserved(start, end); if (ret) { pr_err("'%s' has static call in first %zu bytes, ret=%d\n", func->old_name, KLP_MAX_REPLACE_SIZE, ret); - return -EINVAL; + ret = -EINVAL; + goto out; } } } - return 0; +out: + jump_label_unlock(); + return ret; } static int state_show(struct seq_file *m, void *v)