From aecea96492f52364f852248055921c1b3aacbc91 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Tue, 25 Nov 2025 13:48:47 +0200 Subject: [PATCH] phy: lynx-28g: improve lynx_28g_probe() sequence dev_set_drvdata() is called twice, it is sufficient to do it only once. devm_of_phy_provider_register() can fail, and if it does, the &priv->cdr_check work item is queued, but not cancelled, and the device probing failed, so it will trigger use after free. This is a minor risk though. Resource initialization should be done a little earlier, in case we need to dereference dev_get_drvdata() in lynx_28g_pll_read_configuration() or in lynx_28g_lane_read_configuration(). Signed-off-by: Vladimir Oltean Link: https://patch.msgid.link/20251125114847.804961-16-vladimir.oltean@nxp.com Signed-off-by: Vinod Koul --- drivers/phy/freescale/phy-fsl-lynx-28g.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index 423223371dd0..2b0fd95ba62f 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -1163,7 +1163,11 @@ static int lynx_28g_probe(struct platform_device *pdev) priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->dev = dev; + dev_set_drvdata(dev, priv); + spin_lock_init(&priv->pcc_lock); + INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) @@ -1208,18 +1212,14 @@ static int lynx_28g_probe(struct platform_device *pdev) } } - dev_set_drvdata(dev, priv); - - spin_lock_init(&priv->pcc_lock); - INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); + provider = devm_of_phy_provider_register(dev, lynx_28g_xlate); + if (IS_ERR(provider)) + return PTR_ERR(provider); queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, msecs_to_jiffies(1000)); - dev_set_drvdata(dev, priv); - provider = devm_of_phy_provider_register(dev, lynx_28g_xlate); - - return PTR_ERR_OR_ZERO(provider); + return 0; } static void lynx_28g_remove(struct platform_device *pdev) -- 2.47.3