Skip to content

Commit 2196e81

Browse files
Ma Kebroonie
authored andcommitted
ASoC: codecs: Fix error handling in pm4125 audio codec driver
pm4125_bind() acquires references through pm4125_sdw_device_get() but fails to release them in error paths and during normal unbind operations. This could result in reference count leaks, preventing proper cleanup and potentially causing resource exhaustion over multiple bind/unbind cycles. Calling path: pm4125_sdw_device_get() -> bus_find_device_by_of_node() -> bus_find_device() -> get_device. Found by code review. Cc: stable@vger.kernel.org Fixes: 8ad5294 ("ASoC: codecs: add new pm4125 audio codec driver") Signed-off-by: Ma Ke <make24@iscas.ac.cn> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://patch.msgid.link/20251116033716.29369-1-make24@iscas.ac.cn Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 578ccfe commit 2196e81

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

sound/soc/codecs/pm4125.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,10 @@ static int pm4125_bind(struct device *dev)
15511551
struct device_link *devlink;
15521552
int ret;
15531553

1554+
/* Initialize device pointers to NULL for safe cleanup */
1555+
pm4125->rxdev = NULL;
1556+
pm4125->txdev = NULL;
1557+
15541558
/* Give the soundwire subdevices some more time to settle */
15551559
usleep_range(15000, 15010);
15561560

@@ -1574,7 +1578,7 @@ static int pm4125_bind(struct device *dev)
15741578
if (!pm4125->txdev) {
15751579
dev_err(dev, "could not find txslave with matching of node\n");
15761580
ret = -EINVAL;
1577-
goto error_unbind_all;
1581+
goto error_put_rx;
15781582
}
15791583

15801584
pm4125->sdw_priv[AIF1_CAP] = dev_get_drvdata(pm4125->txdev);
@@ -1584,7 +1588,7 @@ static int pm4125_bind(struct device *dev)
15841588
if (!pm4125->tx_sdw_dev) {
15851589
dev_err(dev, "could not get txslave with matching of dev\n");
15861590
ret = -EINVAL;
1587-
goto error_unbind_all;
1591+
goto error_put_tx;
15881592
}
15891593

15901594
/*
@@ -1596,7 +1600,7 @@ static int pm4125_bind(struct device *dev)
15961600
if (!devlink) {
15971601
dev_err(dev, "Could not devlink TX and RX\n");
15981602
ret = -EINVAL;
1599-
goto error_unbind_all;
1603+
goto error_put_tx;
16001604
}
16011605

16021606
devlink = device_link_add(dev, pm4125->txdev,
@@ -1650,6 +1654,10 @@ static int pm4125_bind(struct device *dev)
16501654
device_link_remove(dev, pm4125->txdev);
16511655
link_remove_rx_tx:
16521656
device_link_remove(pm4125->rxdev, pm4125->txdev);
1657+
error_put_tx:
1658+
put_device(pm4125->txdev);
1659+
error_put_rx:
1660+
put_device(pm4125->rxdev);
16531661
error_unbind_all:
16541662
component_unbind_all(dev, pm4125);
16551663
return ret;
@@ -1663,6 +1671,13 @@ static void pm4125_unbind(struct device *dev)
16631671
device_link_remove(dev, pm4125->txdev);
16641672
device_link_remove(dev, pm4125->rxdev);
16651673
device_link_remove(pm4125->rxdev, pm4125->txdev);
1674+
1675+
/* Release device references acquired in bind */
1676+
if (pm4125->txdev)
1677+
put_device(pm4125->txdev);
1678+
if (pm4125->rxdev)
1679+
put_device(pm4125->rxdev);
1680+
16661681
component_unbind_all(dev, pm4125);
16671682
}
16681683

0 commit comments

Comments
 (0)