1: 3bce6e0ffd8c ! 1: 93881a34dc2b wifi: mt76: mt7915: fix thermal zone use-after-free and cooling device leak @@ Metadata Author: Ryan Leung   ## Commit message ## - wifi: mt76: mt7915: fix thermal zone use-after-free and cooling device leak + wifi: mt76: mt7915: fix thermal zone use-after-free  - The thermal zone registered against the parent device is never torn - down when the phy is unregistered, so it can still be dereferenced - by the thermal core after the phy is freed. The thermal zone and - cooling device are also left registered if a later hwmon - registration step fails during init, leaking both. + The thermal zone registered via devm_thermal_of_zone_register() on the + parent device is never torn down when the phy is unregistered, so the + thermal core can still dereference it after the phy is freed.  - Unregister the thermal zone alongside the cooling device on both the - regular unregister path and the init failure path. Also clear - phy->tzone and phy->cdev after unregistering so that a future caller - invoking the function twice doesn't unregister already-freed objects. + Unregister the thermal zone alongside the cooling device in + mt7915_unregister_thermal(). Also clear phy->tzone and phy->cdev after + unregistering so the function is safe to call when only a subset of + the objects were registered, e.g. after a partially failed + mt7915_thermal_init().  While at it, include the band index in the thermal zone registration warning to help identify which band failed on multi-band chips. @@ drivers/net/wireless/mediatek/mt76/mt7915/init.c: static void mt7915_unregister_ }  static int mt7915_thermal_init(struct mt7915_phy *phy) -@@ drivers/net/wireless/mediatek/mt76/mt7915/init.c: static int mt7915_thermal_init(struct mt7915_phy *phy) - struct thermal_cooling_device *cdev; - struct device *hwmon; - const char *name; -+ int ret; -  - name = devm_kasprintf(&wiphy->dev, GFP_KERNEL, "mt7915_%s", - wiphy_name(wiphy));  @@ drivers/net/wireless/mediatek/mt76/mt7915/init.c: static int mt7915_thermal_init(struct mt7915_phy *phy) if (IS_ERR(phy->tzone)) { if (PTR_ERR(phy->tzone) != -ENODEV) @@ drivers/net/wireless/mediatek/mt76/mt7915/init.c: static int mt7915_thermal_init phy->tzone = NULL; }  -@@ drivers/net/wireless/mediatek/mt76/mt7915/init.c: static int mt7915_thermal_init(struct mt7915_phy *phy) -  - hwmon = devm_hwmon_device_register_with_groups(&wiphy->dev, name, phy, - mt7915_hwmon_groups); -- return PTR_ERR_OR_ZERO(hwmon); -+ ret = PTR_ERR_OR_ZERO(hwmon); -+ if (ret) -+ mt7915_unregister_thermal(phy); -+ -+ return ret; - } -  - static void mt7915_led_set_config(struct led_classdev *led_cdev,