FAILED: patch "[PATCH] net: dsa: bcm_sf2: Fix possible memory leak in" failed to apply to 4.14-stable tree
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-4.14.y
git checkout FETCH_HEAD
git cherry-pick -x 61b40cefe51af005c72dbdcf975a3d166c6e6406
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023102042-clinic-pruning-a3ca@gregkh' --subject-prefix 'PATCH 4.14.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 61b40cefe51af005c72dbdcf975a3d166c6e6406 Mon Sep 17 00:00:00 2001
From: Jinjie Ruan <[email protected]>
Date: Wed, 11 Oct 2023 11:24:19 +0800
Subject: [PATCH] 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.
drivers/net/dsa/bcm_sf2.c +15 -9
@@ -617,17 +617,16 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) dn =of_find_compatible_node (NULL ,NULL ,"brcm,unimac-mdio" ); priv->master_mii_bus =of_mdio_find_bus (dn);if (!priv->master_mii_bus) { -of_node_put (dn); -return -EPROBE_DEFER ; + err = -EPROBE_DEFER ; + goto err_of_node_put; } -get_device (&priv->master_mii_bus->dev); priv->master_mii_dn = dn; priv->slave_mii_bus =mdiobus_alloc ();if (!priv->slave_mii_bus) { -of_node_put (dn); -return -ENOMEM ; + err = -ENOMEM ; + goto err_put_master_mii_bus_dev; } priv->slave_mii_bus->priv = priv;
@@ -684,11 +683,17 @@ static int bcm_sf2_mdio_register(struct dsa_switch *ds) } err =mdiobus_register (priv->slave_mii_bus); -if (err && dn) { -mdiobus_free (priv->slave_mii_bus); -of_node_put (dn); - } +if (err && dn) + goto err_free_slave_mii_bus; +return 0 ; + +err_free_slave_mii_bus: +mdiobus_free (priv->slave_mii_bus); +err_put_master_mii_bus_dev: +put_device (&priv->master_mii_bus->dev); +err_of_node_put: +of_node_put (dn);return err; }
@@ -696,6 +701,7 @@ static void bcm_sf2_mdio_unregister(struct bcm_sf2_priv *priv) {mdiobus_unregister (priv->slave_mii_bus);mdiobus_free (priv->slave_mii_bus); +put_device (&priv->master_mii_bus->dev);of_node_put (priv->master_mii_dn); }