summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Oltean <vladimir.oltean@nxp.com>2022-02-10 19:40:17 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-02-16 12:56:32 +0100
commitf916181692cb5da7050ec0efbf96c915d8ebbbbc (patch)
treea2e165b56f78025975156a6e236458a069838075
parentd98ba26a4ba9b835887e379193be6cee814c7a52 (diff)
downloadlinux-stable-f916181692cb5da7050ec0efbf96c915d8ebbbbc.tar.gz
linux-stable-f916181692cb5da7050ec0efbf96c915d8ebbbbc.tar.bz2
linux-stable-f916181692cb5da7050ec0efbf96c915d8ebbbbc.zip
net: dsa: mv88e6xxx: fix use-after-free in mv88e6xxx_mdios_unregister
[ Upstream commit 51a04ebf21122d5c76a716ecd9bfc33ea44b2b39 ] Since struct mv88e6xxx_mdio_bus *mdio_bus is the bus->priv of something allocated with mdiobus_alloc_size(), this means that mdiobus_free(bus) will free the memory backing the mdio_bus as well. Therefore, the mdio_bus->list element is freed memory, but we continue to iterate through the list of MDIO buses using that list element. To fix this, use the proper list iterator that handles element deletion by keeping a copy of the list element next pointer. Fixes: f53a2ce893b2 ("net: dsa: mv88e6xxx: don't use devres for mdiobus") Reported-by: Rafael Richter <rafael.richter@gin.de> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Link: https://lore.kernel.org/r/20220210174017.3271099-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 206b8a3001b9..056e3b65cd27 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3466,10 +3466,10 @@ out:
static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
{
- struct mv88e6xxx_mdio_bus *mdio_bus;
+ struct mv88e6xxx_mdio_bus *mdio_bus, *p;
struct mii_bus *bus;
- list_for_each_entry(mdio_bus, &chip->mdios, list) {
+ list_for_each_entry_safe(mdio_bus, p, &chip->mdios, list) {
bus = mdio_bus->bus;
if (!mdio_bus->external)