Skip to content

Commit 61b40ce

Browse files
Jinjie Ruankuba-moo
authored andcommitted
net: dsa: bcm_sf2: Fix possible memory leak in bcm_sf2_mdio_register()
In bcm_sf2_mdio_register(), the class_find_device() will call get_device() to increment reference count for priv->master_mii_bus->dev if of_mdio_find_bus() succeeds. If mdiobus_alloc() or mdiobus_register() fails, it will call get_device() twice without decrement reference count for the device. And it is the same if bcm_sf2_mdio_register() succeeds but fails in bcm_sf2_sw_probe(), or if bcm_sf2_sw_probe() succeeds. If the reference count has not decremented to zero, the dev related resource will not be freed. So remove the get_device() in bcm_sf2_mdio_register(), and call put_device() if mdiobus_alloc() or mdiobus_register() fails and in bcm_sf2_mdio_unregister() to solve the issue. And as Simon suggested, unwind from errors for bcm_sf2_mdio_register() and just return 0 if it succeeds to make it cleaner. Fixes: 461cd1b ("net: dsa: bcm_sf2: Register our slave MDIO bus") Signed-off-by: Jinjie Ruan <[email protected]> Suggested-by: Simon Horman <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent dda5e1e commit 61b40ce

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

drivers/net/dsa/bcm_sf2.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -617,17 +617,16 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
617617
dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio");
618618
priv->master_mii_bus = of_mdio_find_bus(dn);
619619
if (!priv->master_mii_bus) {
620-
of_node_put(dn);
621-
return -EPROBE_DEFER;
620+
err = -EPROBE_DEFER;
621+
goto err_of_node_put;
622622
}
623623

624-
get_device(&priv->master_mii_bus->dev);
625624
priv->master_mii_dn = dn;
626625

627626
priv->slave_mii_bus = mdiobus_alloc();
628627
if (!priv->slave_mii_bus) {
629-
of_node_put(dn);
630-
return -ENOMEM;
628+
err = -ENOMEM;
629+
goto err_put_master_mii_bus_dev;
631630
}
632631

633632
priv->slave_mii_bus->priv = priv;
@@ -684,18 +683,25 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds)
684683
}
685684

686685
err = mdiobus_register(priv->slave_mii_bus);
687-
if (err && dn) {
688-
mdiobus_free(priv->slave_mii_bus);
689-
of_node_put(dn);
690-
}
686+
if (err && dn)
687+
goto err_free_slave_mii_bus;
691688

689+
return 0;
690+
691+
err_free_slave_mii_bus:
692+
mdiobus_free(priv->slave_mii_bus);
693+
err_put_master_mii_bus_dev:
694+
put_device(&priv->master_mii_bus->dev);
695+
err_of_node_put:
696+
of_node_put(dn);
692697
return err;
693698
}
694699

695700
static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv)
696701
{
697702
mdiobus_unregister(priv->slave_mii_bus);
698703
mdiobus_free(priv->slave_mii_bus);
704+
put_device(&priv->master_mii_bus->dev);
699705
of_node_put(priv->master_mii_dn);
700706
}
701707

0 commit comments

Comments
 (0)