]> www.infradead.org Git - users/willy/pagecache.git/commitdiff
net: mv643xx_eth: fix an OF node reference leak
authorJoe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
Sat, 21 Dec 2024 08:14:48 +0000 (17:14 +0900)
committerJakub Kicinski <kuba@kernel.org>
Tue, 31 Dec 2024 01:40:34 +0000 (17:40 -0800)
Current implementation of mv643xx_eth_shared_of_add_port() calls
of_parse_phandle(), but does not release the refcount on error. Call
of_node_put() in the error path and in mv643xx_eth_shared_of_remove().

This bug was found by an experimental verification tool that I am
developing.

Fixes: 76723bca2802 ("net: mv643xx_eth: add DT parsing support")
Signed-off-by: Joe Hattori <joe@pf.is.s.u-tokyo.ac.jp>
Link: https://patch.msgid.link/20241221081448.3313163-1-joe@pf.is.s.u-tokyo.ac.jp
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/marvell/mv643xx_eth.c

index a06048719e84437856cf2f97970bfa35523269bb..67a6ff07c83d83fb7890e4fdd18502cf2b236a28 100644 (file)
@@ -2704,9 +2704,15 @@ static struct platform_device *port_platdev[3];
 
 static void mv643xx_eth_shared_of_remove(void)
 {
+       struct mv643xx_eth_platform_data *pd;
        int n;
 
        for (n = 0; n < 3; n++) {
+               if (!port_platdev[n])
+                       continue;
+               pd = dev_get_platdata(&port_platdev[n]->dev);
+               if (pd)
+                       of_node_put(pd->phy_node);
                platform_device_del(port_platdev[n]);
                port_platdev[n] = NULL;
        }
@@ -2769,8 +2775,10 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
        }
 
        ppdev = platform_device_alloc(MV643XX_ETH_NAME, dev_num);
-       if (!ppdev)
-               return -ENOMEM;
+       if (!ppdev) {
+               ret = -ENOMEM;
+               goto put_err;
+       }
        ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
        ppdev->dev.of_node = pnp;
 
@@ -2792,6 +2800,8 @@ static int mv643xx_eth_shared_of_add_port(struct platform_device *pdev,
 
 port_err:
        platform_device_put(ppdev);
+put_err:
+       of_node_put(ppd.phy_node);
        return ret;
 }