[PATCH] phy: ti: phy-ti-pipe3: fix a device reference leak in ti_pipe3_get_sysctrl()
Joe Hattori
joe at pf.is.s.u-tokyo.ac.jp
Tue Dec 17 01:46:20 PST 2024
ti_pipe3_get_sysctrl() calls of_find_device_by_node() to obtain an OF
node reference, but does not release it on error or on removal. Call
put_device() in the error path of ti_pipe3_get_sysctrl() and .probe(),
and in .remove() to fix this.
This bug was found by an experimental verification tool that I am
developing.
Fixes: 73bbc78e57c9 ("phy: ti-pipe3: move sysctrl initialization to a separate function")
Signed-off-by: Joe Hattori <joe at pf.is.s.u-tokyo.ac.jp>
---
drivers/phy/ti/phy-ti-pipe3.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/phy/ti/phy-ti-pipe3.c b/drivers/phy/ti/phy-ti-pipe3.c
index da2cbacb982c..ab3614d169ec 100644
--- a/drivers/phy/ti/phy-ti-pipe3.c
+++ b/drivers/phy/ti/phy-ti-pipe3.c
@@ -719,6 +719,7 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
&phy->pcie_pcs_reg)) {
dev_err(dev,
"couldn't get pcie pcs reg. offset\n");
+ put_device(phy->control_dev);
return -EINVAL;
}
}
@@ -737,6 +738,7 @@ static int ti_pipe3_get_sysctrl(struct ti_pipe3 *phy)
&phy->dpll_reset_reg)) {
dev_err(dev,
"couldn't get pllreset reg. offset\n");
+ put_device(phy->control_dev);
return -EINVAL;
}
}
@@ -808,7 +810,7 @@ static int ti_pipe3_probe(struct platform_device *pdev)
ret = ti_pipe3_get_clk(phy);
if (ret)
- return ret;
+ goto err;
platform_set_drvdata(pdev, phy);
pm_runtime_enable(dev);
@@ -824,15 +826,25 @@ static int ti_pipe3_probe(struct platform_device *pdev)
}
generic_phy = devm_phy_create(dev, NULL, &ops);
- if (IS_ERR(generic_phy))
- return PTR_ERR(generic_phy);
+ if (IS_ERR(generic_phy)) {
+ ret = PTR_ERR(generic_phy);
+ goto err;
+ }
phy_set_drvdata(generic_phy, phy);
ti_pipe3_power_off(generic_phy);
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
- return PTR_ERR_OR_ZERO(phy_provider);
+ if (IS_ERR(phy_provider)) {
+ ret = PTR_ERR(phy_provider);
+ goto err;
+ }
+ return 0;
+
+err:
+ put_device(phy->control_dev);
+ return ret;
}
static void ti_pipe3_remove(struct platform_device *pdev)
@@ -844,6 +856,7 @@ static void ti_pipe3_remove(struct platform_device *pdev)
phy->sata_refclk_enabled = false;
}
pm_runtime_disable(&pdev->dev);
+ put_device(phy->control_dev);
}
static int ti_pipe3_enable_clocks(struct ti_pipe3 *phy)
--
2.34.1
More information about the linux-phy
mailing list