| From foo@baz Mon 17 Aug 2020 11:30:21 AM CEST |
| From: "Marek Behún" <marek.behun@nic.cz> |
| Date: Mon, 10 Aug 2020 17:01:58 +0200 |
| Subject: net: phy: marvell10g: fix null pointer dereference |
| |
| From: "Marek Behún" <marek.behun@nic.cz> |
| |
| [ Upstream commit 1b8ef1423dbfd34de2439a2db457b84480b7c8a8 ] |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/phy/marvell10g.c | 18 +++++++----------- |
| 1 file changed, 7 insertions(+), 11 deletions(-) |
| |
| --- a/drivers/net/phy/marvell10g.c |
| +++ b/drivers/net/phy/marvell10g.c |
| @@ -205,13 +205,6 @@ static int mv3310_hwmon_config(struct ph |
| MV_V2_TEMP_CTRL_MASK, val); |
| } |
| |
| -static void mv3310_hwmon_disable(void *data) |
| -{ |
| - struct phy_device *phydev = data; |
| - |
| - mv3310_hwmon_config(phydev, false); |
| -} |
| - |
| static int mv3310_hwmon_probe(struct phy_device *phydev) |
| { |
| struct device *dev = &phydev->mdio.dev; |
| @@ -235,10 +228,6 @@ static int mv3310_hwmon_probe(struct phy |
| if (ret) |
| return ret; |
| |
| - ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev); |
| - if (ret) |
| - return ret; |
| - |
| priv->hwmon_dev = devm_hwmon_device_register_with_info(dev, |
| priv->hwmon_name, phydev, |
| &mv3310_hwmon_chip_info, NULL); |
| @@ -423,6 +412,11 @@ static int mv3310_probe(struct phy_devic |
| return phy_sfp_probe(phydev, &mv3310_sfp_ops); |
| } |
| |
| +static void mv3310_remove(struct phy_device *phydev) |
| +{ |
| + mv3310_hwmon_config(phydev, false); |
| +} |
| + |
| static int mv3310_suspend(struct phy_device *phydev) |
| { |
| return mv3310_power_down(phydev); |
| @@ -763,6 +757,7 @@ static struct phy_driver mv3310_drivers[ |
| .read_status = mv3310_read_status, |
| .get_tunable = mv3310_get_tunable, |
| .set_tunable = mv3310_set_tunable, |
| + .remove = mv3310_remove, |
| }, |
| { |
| .phy_id = MARVELL_PHY_ID_88E2110, |
| @@ -778,6 +773,7 @@ static struct phy_driver mv3310_drivers[ |
| .read_status = mv3310_read_status, |
| .get_tunable = mv3310_get_tunable, |
| .set_tunable = mv3310_set_tunable, |
| + .remove = mv3310_remove, |
| }, |
| }; |
| |