diff options
| author | Yafang Shao <laoar.shao@gmail.com> | 2026-06-28 19:46:35 +0800 |
|---|---|---|
| committer | Petr Mladek <pmladek@suse.com> | 2026-07-07 12:54:37 +0200 |
| commit | 1a38fd13c31ed8e7c7b598cc975ecc0f41fca468 (patch) | |
| tree | 4ff8254adc748a7702cdf2005b4a5af78e653cd2 /kernel | |
| parent | 0839c8963b7b28d25350bd5ea69bacde794124ab (diff) | |
livepatch: Fix NULL pointer dereference in klp_find_func()
A NULL old_name in a newly loaded livepatch's function entry causes a
NULL pointer dereference in strcmp():
klp_init_patch()
klp_add_nops()
klp_find_func()
strcmp(old_func->old_name, func->old_name)
Add klp_check_patch() at the beginning of klp_enable_patch() to reject
patches with NULL old_name before they reach this code path.
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/live-patching/20260529040130.95A9C1F00893@smtp.kernel.org/
Suggested-by: Petr Mladek <pmladek@suse.com>
Suggested-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Tested-by: Petr Mladek <pmladek@suse.com>
Link: https://patch.msgid.link/20260628114635.33572-1-laoar.shao@gmail.com
Signed-off-by: Petr Mladek <pmladek@suse.com>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/livepatch/core.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 28d15ba58a26..a240d1144e89 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -799,9 +799,6 @@ void klp_free_replaced_patches_async(struct klp_patch *new_patch) static int klp_init_func(struct klp_object *obj, struct klp_func *func) { - if (!func->old_name) - return -EINVAL; - /* * NOPs get the address later. The patched module must be loaded, * see klp_init_object_loaded(). @@ -1092,6 +1089,25 @@ err: return ret; } +static int klp_check_patch(struct klp_patch *patch) +{ + struct klp_object *obj; + struct klp_func *func; + + if (!patch || !patch->mod || !patch->objs) + return -EINVAL; + + klp_for_each_object_static(patch, obj) { + if (!obj->funcs) + return -EINVAL; + klp_for_each_func_static(obj, func) { + if (!func->old_name) + return -EINVAL; + } + } + return 0; +} + /** * klp_enable_patch() - enable the livepatch * @patch: patch to be enabled @@ -1108,16 +1124,10 @@ err: int klp_enable_patch(struct klp_patch *patch) { int ret; - struct klp_object *obj; - - if (!patch || !patch->mod || !patch->objs) - return -EINVAL; - - klp_for_each_object_static(patch, obj) { - if (!obj->funcs) - return -EINVAL; - } + ret = klp_check_patch(patch); + if (ret) + return ret; if (!is_livepatch_module(patch->mod)) { pr_err("module %s is not marked as a livepatch module\n", |
