CVE-2025-37945
Publication date:
20/05/2025
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY<br />
<br />
DSA has 2 kinds of drivers:<br />
<br />
1. Those who call dsa_switch_suspend() and dsa_switch_resume() from<br />
their device PM ops: qca8k-8xxx, bcm_sf2, microchip ksz<br />
2. Those who don&#39;t: all others. The above methods should be optional.<br />
<br />
For type 1, dsa_switch_suspend() calls dsa_user_suspend() -> phylink_stop(),<br />
and dsa_switch_resume() calls dsa_user_resume() -> phylink_start().<br />
These seem good candidates for setting mac_managed_pm = true because<br />
that is essentially its definition [1], but that does not seem to be the<br />
biggest problem for now, and is not what this change focuses on.<br />
<br />
Talking strictly about the 2nd category of DSA drivers here (which<br />
do not have MAC managed PM, meaning that for their attached PHYs,<br />
mdio_bus_phy_suspend() and mdio_bus_phy_resume() should run in full),<br />
I have noticed that the following warning from mdio_bus_phy_resume() is<br />
triggered:<br />
<br />
WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY &&<br />
phydev->state != PHY_UP);<br />
<br />
because the PHY state machine is running.<br />
<br />
It&#39;s running as a result of a previous dsa_user_open() -> ... -><br />
phylink_start() -> phy_start() having been initiated by the user.<br />
<br />
The previous mdio_bus_phy_suspend() was supposed to have called<br />
phy_stop_machine(), but it didn&#39;t. So this is why the PHY is in state<br />
PHY_NOLINK by the time mdio_bus_phy_resume() runs.<br />
<br />
mdio_bus_phy_suspend() did not call phy_stop_machine() because for<br />
phylink, the phydev->adjust_link function pointer is NULL. This seems a<br />
technicality introduced by commit fddd91016d16 ("phylib: fix PAL state<br />
machine restart on resume"). That commit was written before phylink<br />
existed, and was intended to avoid crashing with consumer drivers which<br />
don&#39;t use the PHY state machine - phylink always does, when using a PHY.<br />
But phylink itself has historically not been developed with<br />
suspend/resume in mind, and apparently not tested too much in that<br />
scenario, allowing this bug to exist unnoticed for so long. Plus, prior<br />
to the WARN_ON(), it would have likely been invisible.<br />
<br />
This issue is not in fact restricted to type 2 DSA drivers (according to<br />
the above ad-hoc classification), but can be extrapolated to any MAC<br />
driver with phylink and MDIO-bus-managed PHY PM ops. DSA is just where<br />
the issue was reported. Assuming mac_managed_pm is set correctly, a<br />
quick search indicates the following other drivers might be affected:<br />
<br />
$ grep -Zlr PHYLINK_NETDEV drivers/ | xargs -0 grep -L mac_managed_pm<br />
drivers/net/ethernet/atheros/ag71xx.c<br />
drivers/net/ethernet/microchip/sparx5/sparx5_main.c<br />
drivers/net/ethernet/microchip/lan966x/lan966x_main.c<br />
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c<br />
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c<br />
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c<br />
drivers/net/ethernet/freescale/ucc_geth.c<br />
drivers/net/ethernet/freescale/enetc/enetc_pf_common.c<br />
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c<br />
drivers/net/ethernet/marvell/mvneta.c<br />
drivers/net/ethernet/marvell/prestera/prestera_main.c<br />
drivers/net/ethernet/mediatek/mtk_eth_soc.c<br />
drivers/net/ethernet/altera/altera_tse_main.c<br />
drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c<br />
drivers/net/ethernet/meta/fbnic/fbnic_phylink.c<br />
drivers/net/ethernet/tehuti/tn40_phy.c<br />
drivers/net/ethernet/mscc/ocelot_net.c<br />
<br />
Make the existing conditions dependent on the PHY device having a<br />
phydev->phy_link_change() implementation equal to the default<br />
phy_link_change() provided by phylib. Otherwise, we implicitly know that<br />
the phydev has the phylink-provided phylink_phy_change() callback, and<br />
when phylink is used, the PHY state machine always needs to be stopped/<br />
started on the suspend/resume path. The code is structured as such that<br />
if phydev->phy_link_change() is absent, it is a matter of time until the<br />
kernel will crash - no need to further complicate the test.<br />
<br />
Thus, for the situation where the PM is not managed b<br />
---truncated---
Severity CVSS v4.0: Pending analysis
Last modification:
06/04/2026