[PATCH 7/7] ASoC: mediatek: mt8188: fix clk leak on error in audsys_clk_register
phucduc.bui at gmail.com
phucduc.bui at gmail.com
Mon Sep 7 05:03:10 PDT 2026
From: bui duc phuc <phucduc.bui at gmail.com>
devm_add_action_or_reset() is called after the loop that registers gate
clocks. If kzalloc() fails mid-loop, the function returns -ENOMEM before
that call, so cleanup is never registered and all previously registered
clocks leak permanently.
Move devm_add_action_or_reset() before the loop so cleanup is always
scheduled. The clock from the current (failing) iteration is not yet
stored in afe_priv->lookup[i], so it still needs an explicit
clk_unregister_gate() call.
Fixes: fd67a7a1a22c ("ASoC: mediatek: mt8188: fix use-after-free in driver remove path")
Signed-off-by: bui duc phuc <phucduc.bui at gmail.com>
---
sound/soc/mediatek/mt8188/mt8188-audsys-clk.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
index 972f097a13ca..9f3b3a777577 100644
--- a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
+++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
@@ -170,7 +170,7 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
- int i;
+ int i, ret;
afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
sizeof(*afe_priv->lookup),
@@ -179,6 +179,10 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
if (!afe_priv->lookup)
return -ENOMEM;
+ ret = devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
+ if (ret)
+ return ret;
+
for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
const struct afe_gate *gate = &aud_clks[i];
@@ -194,8 +198,10 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
/* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
cl = kzalloc_obj(*cl);
- if (!cl)
+ if (!cl) {
+ clk_unregister_gate(clk);
return -ENOMEM;
+ }
cl->clk = clk;
cl->con_id = gate->name;
@@ -206,5 +212,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
afe_priv->lookup[i] = cl;
}
- return devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
+ return 0;
}
--
2.43.0
More information about the linux-arm-kernel
mailing list