Skip to content

Commit 41ff66b

Browse files
committed
thermal: core: Fix thermal zone governor cleanup issues
If thermal_zone_device_register_with_trips() fails after adding a thermal governor to the thermal zone being registered, the governor is not removed from it as appropriate which may lead to a memory leak. In turn, thermal_zone_device_unregister() calls thermal_set_governor() without acquiring the thermal zone lock beforehand which may race with a governor update via sysfs and may lead to a use-after-free in that case. Address these issues by adding two thermal_set_governor() calls, one to thermal_release() to remove the governor from the given thermal zone, and one to the thermal zone registration error path to cover failures preceding the thermal zone device registration. Fixes: e33df1d ("thermal: let governors have private data for each thermal zone") Cc: All applicable <stable@vger.kernel.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://patch.msgid.link/5092923.31r3eYUQgx@rafael.j.wysocki
1 parent 761fdf4 commit 41ff66b

1 file changed

Lines changed: 4 additions & 3 deletions

File tree

drivers/thermal/thermal_core.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,7 @@ static void thermal_release(struct device *dev)
964964
sizeof("thermal_zone") - 1)) {
965965
tz = to_thermal_zone(dev);
966966
thermal_zone_destroy_device_groups(tz);
967+
thermal_set_governor(tz, NULL);
967968
mutex_destroy(&tz->lock);
968969
complete(&tz->removal);
969970
} else if (!strncmp(dev_name(dev), "cooling_device",
@@ -1610,8 +1611,10 @@ thermal_zone_device_register_with_trips(const char *type,
16101611
/* sys I/F */
16111612
/* Add nodes that are always present via .groups */
16121613
result = thermal_zone_create_device_groups(tz);
1613-
if (result)
1614+
if (result) {
1615+
thermal_set_governor(tz, NULL);
16141616
goto remove_id;
1617+
}
16151618

16161619
result = device_register(&tz->device);
16171620
if (result)
@@ -1724,8 +1727,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
17241727

17251728
cancel_delayed_work_sync(&tz->poll_queue);
17261729

1727-
thermal_set_governor(tz, NULL);
1728-
17291730
thermal_thresholds_exit(tz);
17301731
thermal_remove_hwmon_sysfs(tz);
17311732
ida_free(&thermal_tz_ida, tz->id);

0 commit comments

Comments
 (0)