summaryrefslogtreecommitdiff
path: root/kernel/livepatch
diff options
context:
space:
mode:
authorYafang Shao <laoar.shao@gmail.com>2026-06-28 19:46:35 +0800
committerPetr Mladek <pmladek@suse.com>2026-07-07 12:54:37 +0200
commit1a38fd13c31ed8e7c7b598cc975ecc0f41fca468 (patch)
tree4ff8254adc748a7702cdf2005b4a5af78e653cd2 /kernel/livepatch
parent0839c8963b7b28d25350bd5ea69bacde794124ab (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/livepatch')
-rw-r--r--kernel/livepatch/core.c34
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",