From: "Rafael J. Wysocki" rafael.j.wysocki@intel.com
mainline inclusion from mainline-v6.12-rc3 commit a42a5839f400e929c489bb1b58f54596c4535167 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRF5 CVE: CVE-2024-50028
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
There are places in the thermal netlink code where nothing prevents the thermal zone object from going away while being accessed after it has been returned by thermal_zone_get_by_id().
To address this, make thermal_zone_get_by_id() get a reference on the thermal zone device object to be returned with the help of get_device(), under thermal_list_lock, and adjust all of its callers to this change with the help of the cleanup.h infrastructure.
Fixes: 1ce50e7d408e ("thermal: core: genetlink support for events/cmd/sampling") Cc: 6.8+ stable@vger.kernel.org # 6.8+ Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Reviewed-by: Lukasz Luba lukasz.luba@arm.com Link: https://patch.msgid.link/6112242.lOV4Wx5bFT@rjwysocki.net
Conflicts: drivers/thermal/thermal_netlink.c [wangxiongfeng: fix conflict because __cleanup() based infrastructure DEFINE_CLASS() is not introduced.] Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com --- drivers/thermal/thermal_core.c | 1 + drivers/thermal/thermal_netlink.c | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index dd449945e1e5e..ae7feac0892e2 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -760,6 +760,7 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id) mutex_lock(&thermal_list_lock); list_for_each_entry(tz, &thermal_tz_list, node) { if (tz->id == id) { + get_device(&tz->device); match = tz; break; } diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c index dc535831b6609..5a9a6d1ddd03d 100644 --- a/drivers/thermal/thermal_netlink.c +++ b/drivers/thermal/thermal_netlink.c @@ -463,8 +463,10 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) return -EINVAL;
start_trip = nla_nest_start(msg, THERMAL_GENL_ATTR_TZ_TRIP); - if (!start_trip) + if (!start_trip) { + put_device(&tz->device); return -EMSGSIZE; + }
mutex_lock(&tz->lock);
@@ -489,10 +491,13 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p)
nla_nest_end(msg, start_trip);
+ put_device(&tz->device); + return 0;
out_cancel_nest: mutex_unlock(&tz->lock); + put_device(&tz->device);
return -EMSGSIZE; } @@ -514,13 +519,17 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p)
ret = thermal_zone_get_temp(tz, &temp); if (ret) - return ret; + goto out;
if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id) || - nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TEMP, temp)) - return -EMSGSIZE; + nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_TEMP, temp)) { + ret = -EMSGSIZE; + goto out; + }
- return 0; +out: + put_device(&tz->device); + return ret; }
static int thermal_genl_cmd_tz_get_gov(struct param *p) @@ -542,10 +551,13 @@ static int thermal_genl_cmd_tz_get_gov(struct param *p)
if (nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id) || nla_put_string(msg, THERMAL_GENL_ATTR_TZ_GOV_NAME, - tz->governor->name)) + tz->governor->name)) { + put_device(&tz->device); ret = -EMSGSIZE; + }
mutex_unlock(&tz->lock); + put_device(&tz->device);
return ret; }