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

net: phy: marvell10g: fix null pointer dereference

Commit c3e302edca24 ("net: phy: marvell10g: fix temperature sensor on 2110")
added a check for PHY ID via phydev->drv->phy_id in a function which is
called by devres at a time when phydev->drv is already set to null by
phy_remove function.

This null pointer dereference can be triggered via SFP subsystem with a
SFP module containing this Marvell PHY. When the SFP interface is put
down, the SFP subsystem removes the PHY.

Fixes: c3e302edca24 ("net: phy: marvell10g: fix temperature sensor on 2110")
Signed-off-by: Marek Behún <marek.behun@nic.cz>
Cc: Maxime Chevallier <maxime.chevallier@bootlin.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Baruch Siach <baruch@tkos.co.il>
Cc: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Marek Behún and committed by
David S. Miller
1b8ef142 0f5907af

+7 -11
+7 -11
drivers/net/phy/marvell10g.c
··· 208 208 MV_V2_TEMP_CTRL_MASK, val); 209 209 } 210 210 211 - static void mv3310_hwmon_disable(void *data) 212 - { 213 - struct phy_device *phydev = data; 214 - 215 - mv3310_hwmon_config(phydev, false); 216 - } 217 - 218 211 static int mv3310_hwmon_probe(struct phy_device *phydev) 219 212 { 220 213 struct device *dev = &phydev->mdio.dev; ··· 228 235 priv->hwmon_name[j] = '\0'; 229 236 230 237 ret = mv3310_hwmon_config(phydev, true); 231 - if (ret) 232 - return ret; 233 - 234 - ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev); 235 238 if (ret) 236 239 return ret; 237 240 ··· 413 424 return ret; 414 425 415 426 return phy_sfp_probe(phydev, &mv3310_sfp_ops); 427 + } 428 + 429 + static void mv3310_remove(struct phy_device *phydev) 430 + { 431 + mv3310_hwmon_config(phydev, false); 416 432 } 417 433 418 434 static int mv3310_suspend(struct phy_device *phydev) ··· 778 784 .read_status = mv3310_read_status, 779 785 .get_tunable = mv3310_get_tunable, 780 786 .set_tunable = mv3310_set_tunable, 787 + .remove = mv3310_remove, 781 788 }, 782 789 { 783 790 .phy_id = MARVELL_PHY_ID_88E2110, ··· 793 798 .read_status = mv3310_read_status, 794 799 .get_tunable = mv3310_get_tunable, 795 800 .set_tunable = mv3310_set_tunable, 801 + .remove = mv3310_remove, 796 802 }, 797 803 }; 798 804