Patch "net: dsa: Fix possible memory leaks in dsa_loop_init()" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net: dsa: Fix possible memory leaks in dsa_loop_init()

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-dsa-fix-possible-memory-leaks-in-dsa_loop_init.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 3780002d1fcf5fc87dea659c96cf4bfd33ed3d03
Author: Chen Zhongjin <chenzhongjin@xxxxxxxxxx>
Date:   Wed Oct 26 10:03:21 2022 +0800

    net: dsa: Fix possible memory leaks in dsa_loop_init()
    
    [ Upstream commit 633efc8b3dc96f56f5a57f2a49764853a2fa3f50 ]
    
    kmemleak reported memory leaks in dsa_loop_init():
    
    kmemleak: 12 new suspected memory leaks
    
    unreferenced object 0xffff8880138ce000 (size 2048):
      comm "modprobe", pid 390, jiffies 4295040478 (age 238.976s)
      backtrace:
        [<000000006a94f1d5>] kmalloc_trace+0x26/0x60
        [<00000000a9c44622>] phy_device_create+0x5d/0x970
        [<00000000d0ee2afc>] get_phy_device+0xf3/0x2b0
        [<00000000dca0c71f>] __fixed_phy_register.part.0+0x92/0x4e0
        [<000000008a834798>] fixed_phy_register+0x84/0xb0
        [<0000000055223fcb>] dsa_loop_init+0xa9/0x116 [dsa_loop]
        ...
    
    There are two reasons for memleak in dsa_loop_init().
    
    First, fixed_phy_register() create and register phy_device:
    
    fixed_phy_register()
      get_phy_device()
        phy_device_create() # freed by phy_device_free()
      phy_device_register() # freed by phy_device_remove()
    
    But fixed_phy_unregister() only calls phy_device_remove().
    So the memory allocated in phy_device_create() is leaked.
    
    Second, when mdio_driver_register() fail in dsa_loop_init(),
    it just returns and there is no cleanup for phydevs.
    
    Fix the problems by catching the error of mdio_driver_register()
    in dsa_loop_init(), then calling both fixed_phy_unregister() and
    phy_device_free() to release phydevs.
    Also add a function for phydevs cleanup to avoid duplacate.
    
    Fixes: 98cd1552ea27 ("net: dsa: Mock-up driver")
    Signed-off-by: Chen Zhongjin <chenzhongjin@xxxxxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index 0df6c2b9484a..e99e38c6738e 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -329,6 +329,17 @@ static struct mdio_driver dsa_loop_drv = {
 
 #define NUM_FIXED_PHYS	(DSA_LOOP_NUM_PORTS - 2)
 
+static void dsa_loop_phydevs_unregister(void)
+{
+	unsigned int i;
+
+	for (i = 0; i < NUM_FIXED_PHYS; i++)
+		if (!IS_ERR(phydevs[i])) {
+			fixed_phy_unregister(phydevs[i]);
+			phy_device_free(phydevs[i]);
+		}
+}
+
 static int __init dsa_loop_init(void)
 {
 	struct fixed_phy_status status = {
@@ -336,23 +347,23 @@ static int __init dsa_loop_init(void)
 		.speed = SPEED_100,
 		.duplex = DUPLEX_FULL,
 	};
-	unsigned int i;
+	unsigned int i, ret;
 
 	for (i = 0; i < NUM_FIXED_PHYS; i++)
 		phydevs[i] = fixed_phy_register(PHY_POLL, &status, NULL);
 
-	return mdio_driver_register(&dsa_loop_drv);
+	ret = mdio_driver_register(&dsa_loop_drv);
+	if (ret)
+		dsa_loop_phydevs_unregister();
+
+	return ret;
 }
 module_init(dsa_loop_init);
 
 static void __exit dsa_loop_exit(void)
 {
-	unsigned int i;
-
 	mdio_driver_unregister(&dsa_loop_drv);
-	for (i = 0; i < NUM_FIXED_PHYS; i++)
-		if (!IS_ERR(phydevs[i]))
-			fixed_phy_unregister(phydevs[i]);
+	dsa_loop_phydevs_unregister();
 }
 module_exit(dsa_loop_exit);
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux