[SRU][J][PATCH 1/1] ASoC: codecs: wcd9335: Fix missing free of regulator supplies
Cengiz Can
cengiz.can at canonical.com
Thu Sep 10 22:04:57 UTC 2026
From: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Driver gets and enables all regulator supplies in probe path
(wcd9335_parse_dt() and wcd9335_power_on_reset()), but does not cleanup
in final error paths and in unbind (missing remove() callback). This
leads to leaked memory and unbalanced regulator enable count during
probe errors or unbind.
Fix this by converting entire code into devm_regulator_bulk_get_enable()
which also greatly simplifies the code.
Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec")
Cc: stable at vger.kernel.org
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at linaro.org>
Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2993b7d3@linaro.org
Signed-off-by: Mark Brown <broonie at kernel.org>
(backported from commit 9079db287fc3e38e040b0edeb0a25770bb679c8e)
[bot_kybele: devm_regulator_bulk_get_enable() does not exist in 5.15;
reimplemented its semantics: kept supplies[] struct field and names, used
devm_regulator_bulk_get (fixes free leak) plus regulator_bulk_enable in
parse_dt with devm_add_action_or_reset(wcd9335_disable_supplies) to disable on
unbind/error (fixes enable imbalance); dropped the added wcd9335_supplies name
array; enable already removed from power_on_reset.]
CVE-2025-38259
Assisted-by: kybele:claude-opus-4.8
Signed-off-by: Cengiz Can <cengiz.can at canonical.com>
---
sound/soc/codecs/wcd9335.c | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index 075ed20e9fad..1a60e8933e7c 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -5021,6 +5021,13 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = {
.num_irqs = ARRAY_SIZE(wcd9335_codec_irqs),
};
+static void wcd9335_disable_supplies(void *data)
+{
+ struct wcd9335_codec *wcd = data;
+
+ regulator_bulk_disable(WCD9335_MAX_SUPPLY, wcd->supplies);
+}
+
static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
{
struct device *dev = wcd->dev;
@@ -5051,26 +5058,23 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd)
wcd->supplies[3].supply = "vdd-rx";
wcd->supplies[4].supply = "vdd-io";
- ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
- if (ret) {
- dev_err(dev, "Failed to get supplies: err = %d\n", ret);
+ ret = devm_regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get supplies\n");
+
+ ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable supplies\n");
+
+ ret = devm_add_action_or_reset(dev, wcd9335_disable_supplies, wcd);
+ if (ret)
return ret;
- }
return 0;
}
static int wcd9335_power_on_reset(struct wcd9335_codec *wcd)
{
- struct device *dev = wcd->dev;
- int ret;
-
- ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies);
- if (ret) {
- dev_err(dev, "Failed to get supplies: err = %d\n", ret);
- return ret;
- }
-
/*
* For WCD9335, it takes about 600us for the Vout_A and
* Vout_D to be ready after BUCK_SIDO is powered up.
--
2.53.0
More information about the kernel-team
mailing list