Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: e33df1d2f3a0 ("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

+4 -3
+4 -3
drivers/thermal/thermal_core.c
··· 964 964 sizeof("thermal_zone") - 1)) { 965 965 tz = to_thermal_zone(dev); 966 966 thermal_zone_destroy_device_groups(tz); 967 + thermal_set_governor(tz, NULL); 967 968 mutex_destroy(&tz->lock); 968 969 complete(&tz->removal); 969 970 } else if (!strncmp(dev_name(dev), "cooling_device", ··· 1611 1610 /* sys I/F */ 1612 1611 /* Add nodes that are always present via .groups */ 1613 1612 result = thermal_zone_create_device_groups(tz); 1614 - if (result) 1613 + if (result) { 1614 + thermal_set_governor(tz, NULL); 1615 1615 goto remove_id; 1616 + } 1616 1617 1617 1618 result = device_register(&tz->device); 1618 1619 if (result) ··· 1726 1723 return; 1727 1724 1728 1725 cancel_delayed_work_sync(&tz->poll_queue); 1729 - 1730 - thermal_set_governor(tz, NULL); 1731 1726 1732 1727 thermal_thresholds_exit(tz); 1733 1728 thermal_remove_hwmon_sysfs(tz);