lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20251025160905.3857885-3-sashal@kernel.org>
Date: Sat, 25 Oct 2025 11:53:54 -0400
From: Sasha Levin <sashal@...nel.org>
To: patches@...ts.linux.dev,
	stable@...r.kernel.org
Cc: Heiner Kallweit <hkallweit1@...il.com>,
	"Russell King (Oracle)" <rmk+kernel@...linux.org.uk>,
	Jakub Kicinski <kuba@...nel.org>,
	Sasha Levin <sashal@...nel.org>,
	andrew@...n.ch,
	olteanv@...il.com,
	netdev@...r.kernel.org
Subject: [PATCH AUTOSEL 6.17-6.1] net: phy: fixed_phy: let fixed_phy_unregister free the phy_device

From: Heiner Kallweit <hkallweit1@...il.com>

[ Upstream commit a0f849c1cc6df0db9083b4c81c05a5456b1ed0fb ]

fixed_phy_register() creates and registers the phy_device. To be
symmetric, we should not only unregister, but also free the phy_device
in fixed_phy_unregister(). This allows to simplify code in users.

Note wrt of_phy_deregister_fixed_link():
put_device(&phydev->mdio.dev) and phy_device_free(phydev) are identical.

Signed-off-by: Heiner Kallweit <hkallweit1@...il.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@...linux.org.uk>
Link: https://patch.msgid.link/ad8dda9a-10ed-4060-916b-3f13bdbb899d@gmail.com
Signed-off-by: Jakub Kicinski <kuba@...nel.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---

LLM Generated explanations, may be completely bogus:

YES

- Fix rationale and scope
  - The change fixes an API asymmetry and a potential memory leak:
    `fixed_phy_register()` allocates and registers a `phy_device`, but
    pre‑patch `fixed_phy_unregister()` only removed it without freeing.
    The commit makes `fixed_phy_unregister()` also free the
    `phy_device`, preventing leaks and simplifying callers.
  - The change is small and localized to fixed PHY/MDIO code; it does
    not alter uAPI or architecture.

- Core change
  - `drivers/net/phy/fixed_phy.c:230` now frees the `phy_device` after
    removal:
    - Calls `phy_device_remove(phy)`, `of_node_put(...)`,
      `fixed_phy_del(...)`, and then `phy_device_free(phy)` to drop the
      device reference and free when the refcount reaches zero.
  - `phy_device_free()` is just a `put_device(&phydev->mdio.dev)`:
    - `drivers/net/phy/phy_device.c:212` confirms that
      `phy_device_free()` equals a `put_device`, matching the commit
      note about identical behavior.

- Callers adjusted to avoid double-free
  - `drivers/net/dsa/dsa_loop.c:398` removes the explicit
    `phy_device_free(phydevs[i])` after
    `fixed_phy_unregister(phydevs[i])`.
  - `drivers/net/mdio/of_mdio.c:475` now calls only
    `fixed_phy_unregister(phydev)` followed by
    `put_device(&phydev->mdio.dev)` at `drivers/net/mdio/of_mdio.c:477`,
    which correctly drops the extra reference obtained by
    `of_phy_find_device(np)` (see `drivers/net/mdio/of_mdio.c:471`).
    This is safe because `fixed_phy_unregister()`’s `phy_device_free()`
    and the extra `put_device()` account for two separate refs (the
    device’s own and the one grabbed by `of_phy_find_device()`).

- Other in-tree users remain correct and benefit
  - Callers which already did not free explicitly remain correct and now
    won’t leak:
    - Example: `drivers/net/ethernet/faraday/ftgmac100.c:1763` calls
      `fixed_phy_unregister(phydev)` (after `phy_disconnect()`), and
      does not call `phy_device_free()`.
    - `drivers/net/ethernet/hisilicon/hibmcge/hbg_mdio.c:236` similarly
      calls only `fixed_phy_unregister((struct phy_device *)data)`.
  - We searched for all in-tree callers of `fixed_phy_unregister()` and
    `of_phy_deregister_fixed_link()` and found no remaining explicit
    frees which would cause a double free.

- Risk and stable suitability
  - Minimal regression risk: change is contained, behavior is well-
    defined, and in‑tree callers are updated or already compatible. No
    architectural changes; no uAPI impact.
  - Positive impact: fixes a likely leak for paths that didn’t free
    after unregister (e.g., NCSI fixed PHY path in `ftgmac100`).
  - Meets stable criteria: it’s a bug fix (memory management), small and
    self-contained, with low risk of regression.

 drivers/net/dsa/dsa_loop.c  | 9 +++------
 drivers/net/mdio/of_mdio.c  | 1 -
 drivers/net/phy/fixed_phy.c | 1 +
 3 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index d8a35f25a4c82..ad907287a853a 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -386,13 +386,10 @@ static struct mdio_driver dsa_loop_drv = {
 
 static void dsa_loop_phydevs_unregister(void)
 {
-	unsigned int i;
-
-	for (i = 0; i < NUM_FIXED_PHYS; i++)
-		if (!IS_ERR(phydevs[i])) {
+	for (int 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)
diff --git a/drivers/net/mdio/of_mdio.c b/drivers/net/mdio/of_mdio.c
index 98f667b121f7d..d8ca63ed87194 100644
--- a/drivers/net/mdio/of_mdio.c
+++ b/drivers/net/mdio/of_mdio.c
@@ -473,6 +473,5 @@ void of_phy_deregister_fixed_link(struct device_node *np)
 	fixed_phy_unregister(phydev);
 
 	put_device(&phydev->mdio.dev);	/* of_phy_find_device() */
-	phy_device_free(phydev);	/* fixed_phy_register() */
 }
 EXPORT_SYMBOL(of_phy_deregister_fixed_link);
diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c
index 033656d574b89..b8bec7600ef8e 100644
--- a/drivers/net/phy/fixed_phy.c
+++ b/drivers/net/phy/fixed_phy.c
@@ -309,6 +309,7 @@ void fixed_phy_unregister(struct phy_device *phy)
 	phy_device_remove(phy);
 	of_node_put(phy->mdio.dev.of_node);
 	fixed_phy_del(phy->mdio.addr);
+	phy_device_free(phy);
 }
 EXPORT_SYMBOL_GPL(fixed_phy_unregister);
 
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ