mainline inclusion from mainline-v7.3-rc1 commit 3dfaae04243cde460d82dfc2a7dd0bb6664d20ae category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/18886 CVE: CVE-2026-89552 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- param_set_charp() stores charp parameters in allocated memory after slab is available, and releases the previous value when the parameter is updated. The previous value is released before the replacement allocation succeeds. If kmalloc_parameter() fails, the setter returns -ENOMEM with the parameter left as NULL. Failing zswap's compressor update before zswap is initialized can later trigger: BUG: kernel NULL pointer dereference, address: 0000000000000000 RIP: 0010:strcmp+0x10/0x30 Call Trace: zswap_setup+0x3b1/0x490 zswap_enabled_param_set+0x5b/0xa0 param_attr_store+0x93/0xe0 module_attr_store+0x1c/0x30 kernfs_fop_write_iter+0x116/0x1f0 Allocate and copy the replacement first, then replace the parameter value only after allocation succeeds. Fixes: e180a6b7759a ("param: fix charp parameters set via sysfs") Cc: stable@vger.kernel.org Upstream commit 3dfaae04243cde460d82dfc2a7dd0bb6664d20ae Signed-off-by: Jiacheng Yu <yujiacheng3@huawei.com> Reviewed-by: Petr Pavlu <petr.pavlu@suse.com> Signed-off-by: Petr Pavlu <petr.pavlu@suse.com> Conflicts: kernel/params.c [The upstream hunk context relies on e180a6b7759a ("param: fix charp parameters set via sysfs"), which is absent in this tree; keep the existing strlen() length check and use strcpy(tmp, val) with strlen(val) + 1 for the allocation.] Co-authored-by: BackportAgent@a:deepseek-v4.1-flash Signed-off-by: Hulk Robot <hulkrobot@huawei.com> Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com> Signed-off-by: Pan Taixi <pantaixi1@huawei.com> --- kernel/params.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/kernel/params.c b/kernel/params.c index 9d09ea99363f..d7afd70cfe45 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -262,26 +262,29 @@ int param_set_uint_minmax(const char *val, const struct kernel_param *kp, } EXPORT_SYMBOL_GPL(param_set_uint_minmax); int param_set_charp(const char *val, const struct kernel_param *kp) { + char *tmp; + if (strlen(val) > 1024) { pr_err("%s: string parameter too long\n", kp->name); return -ENOSPC; } - maybe_kfree_parameter(*(char **)kp->arg); - /* This is a hack. We can't kmalloc in early boot, and we * don't need to; this mangled commandline is preserved. */ if (slab_is_available()) { - *(char **)kp->arg = kmalloc_parameter(strlen(val)+1); - if (!*(char **)kp->arg) + tmp = kmalloc_parameter(strlen(val) + 1); + if (!tmp) return -ENOMEM; - strcpy(*(char **)kp->arg, val); + strcpy(tmp, val); } else - *(const char **)kp->arg = val; + tmp = (char *)val; + + maybe_kfree_parameter(*(char **)kp->arg); + *(char **)kp->arg = tmp; return 0; } EXPORT_SYMBOL(param_set_charp); -- 2.34.1