diff mbox series

phy: mdio: fix memory leak

Message ID 20210927112017.19108-1-paskripkin@gmail.com (mailing list archive)
State Not Applicable
Delegated to: Netdev Maintainers
Headers show
Series phy: mdio: fix memory leak | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Guessed tree name to be net-next
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cc_maintainers fail 1 blamed authors not CCed: afleming@freescale.com; 1 maintainers not CCed: afleming@freescale.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 458 this patch: 458
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch warning WARNING: Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON() WARNING: line length of 91 exceeds 80 columns
netdev/build_allmodconfig_warn success Errors and warnings before: 375 this patch: 375
netdev/header_inline success Link

Commit Message

Pavel Skripkin Sept. 27, 2021, 11:20 a.m. UTC
Syzbot reported memory leak in MDIO bus interface, the problem was in
wrong state logic.

MDIOBUS_ALLOCATED indicates 2 states:
	1. Bus is only allocated
	2. Bus allocated and __mdiobus_register() fails, but
	   device_register() was called

In case of device_register() has been called we should call put_device()
to correctly free the memory allocated for this device, but mdiobus_free()
was just calling kfree(dev) in case of MDIOBUS_ALLOCATED state

To avoid this behaviour we can add new intermediate state, which means,
that we have called device_regiter(), but failed on any of the next steps.
Clean up process for this state is the same as for MDIOBUS_UNREGISTERED,
but MDIOBUS_UNREGISTERED name does not fit to the logic described above.

Fixes: 46abc02175b3 ("phylib: give mdio buses a device tree presence")
Reported-and-tested-by: syzbot+398e7dc692ddbbb4cfec@syzkaller.appspotmail.com
Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>
---
 drivers/net/phy/mdio_bus.c | 4 +++-
 include/linux/phy.h        | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

Comments

Pavel Skripkin Sept. 27, 2021, 7:17 p.m. UTC | #1
On 9/27/21 14:20, Pavel Skripkin wrote:
> Syzbot reported memory leak in MDIO bus interface, the problem was in
> wrong state logic.
> 
> MDIOBUS_ALLOCATED indicates 2 states:
> 	1. Bus is only allocated
> 	2. Bus allocated and __mdiobus_register() fails, but
> 	   device_register() was called
> 
> In case of device_register() has been called we should call put_device()
> to correctly free the memory allocated for this device, but mdiobus_free()
> was just calling kfree(dev) in case of MDIOBUS_ALLOCATED state
> 
> To avoid this behaviour we can add new intermediate state, which means,
> that we have called device_regiter(), but failed on any of the next steps.
> Clean up process for this state is the same as for MDIOBUS_UNREGISTERED,
> but MDIOBUS_UNREGISTERED name does not fit to the logic described above.
> 
> Fixes: 46abc02175b3 ("phylib: give mdio buses a device tree presence")
> Reported-and-tested-by: syzbot+398e7dc692ddbbb4cfec@syzkaller.appspotmail.com
> Signed-off-by: Pavel Skripkin <paskripkin@gmail.com>


I've just found, that this syzkaller bug has been closed by Yanfei's 
patch [1], but Yanfei's Reported-by: is wrong, IMO.

Yanfei's patch fixed other memory leak and it's not related to bug 
reported by syzkaller. If you take a look at log [2] you won't find 
error message about mii_bus registration failure, i.e the error happened 
a bit latter (more precisely in mdiobus_scan()).

Since, Yanfei's patch is already applied, we cannot remove this tag, so 
I am informing you about this situation to break possible confusions 
about 2 different patches with same Reported-by: tag :)


Thanks


[1] 
https://lore.kernel.org/netdev/20210926045313.2267655-1-yanfei.xu@windriver.com/

[2] https://syzkaller.appspot.com/text?tag=CrashLog&x=131c754b300000


With regards,
Pavel Skripkin
diff mbox series

Patch

diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 53f034fc2ef7..ed764638b449 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -540,6 +540,8 @@  int __mdiobus_register(struct mii_bus *bus, struct module *owner)
 		return -EINVAL;
 	}
 
+	bus->state = MDIOBUS_DEV_REGISTERED;
+
 	mutex_init(&bus->mdio_lock);
 	mutex_init(&bus->shared_lock);
 
@@ -647,7 +649,7 @@  void mdiobus_free(struct mii_bus *bus)
 		return;
 	}
 
-	BUG_ON(bus->state != MDIOBUS_UNREGISTERED);
+	BUG_ON(bus->state != MDIOBUS_UNREGISTERED && bus->state != MDIOBUS_DEV_REGISTERED);
 	bus->state = MDIOBUS_RELEASED;
 
 	put_device(&bus->dev);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 736e1d1a47c4..41d2ccdacd5e 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -343,6 +343,7 @@  struct mii_bus {
 		MDIOBUS_REGISTERED,
 		MDIOBUS_UNREGISTERED,
 		MDIOBUS_RELEASED,
+		MDIOBUS_DEV_REGISTERED,
 	} state;
 
 	/** @dev: Kernel device representation */