Skip to content

Commit fd67a7a

Browse files
wenliangwubroonie
authored andcommitted
ASoC: mediatek: mt8188: fix use-after-free in driver remove path
During mt8188_afe_init_clock(), mt8188_audsys_clk_register() was called followed by several other devm functions. The caller of mt8188_afe_init_clock() utilized devm_add_action_or_reset() to call mt8188_afe_deinit_clock(). However, the order was incorrect, causing a use-after-free issue during remove time. At probe time, the order of calls was: 1. mt8188_audsys_clk_register 2. afe_priv->clk = devm_kcalloc 3. afe_priv->clk[i] = devm_clk_get At remove time, the order of calls was: 1. mt8188_audsys_clk_unregister 3. free afe_priv->clk[i] 2. free afe_priv->clk To resolve the problem, it's necessary to move devm_add_action_or_reset() to the appropriate position so that the remove order can be 3->2->1. Fixes: f6b0264 ("ASoC: mediatek: mt8188: support audio clock control") Signed-off-by: Trevor Wu <trevor.wu@mediatek.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20230601033318.10408-2-trevor.wu@mediatek.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 57d1e89 commit fd67a7a

File tree

5 files changed

+24
-36
lines changed

5 files changed

+24
-36
lines changed

sound/soc/mediatek/mt8188/mt8188-afe-clk.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -418,13 +418,6 @@ int mt8188_afe_init_clock(struct mtk_base_afe *afe)
418418
return 0;
419419
}
420420

421-
void mt8188_afe_deinit_clock(void *priv)
422-
{
423-
struct mtk_base_afe *afe = priv;
424-
425-
mt8188_audsys_clk_unregister(afe);
426-
}
427-
428421
int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
429422
{
430423
int ret;

sound/soc/mediatek/mt8188/mt8188-afe-clk.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ int mt8188_afe_get_mclk_source_clk_id(int sel);
100100
int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
101101
int mt8188_afe_get_default_mclk_source_by_rate(int rate);
102102
int mt8188_afe_init_clock(struct mtk_base_afe *afe);
103-
void mt8188_afe_deinit_clock(void *priv);
104103
int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
105104
void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
106105
int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,

sound/soc/mediatek/mt8188/mt8188-afe-pcm.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3185,10 +3185,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
31853185
if (ret)
31863186
return dev_err_probe(dev, ret, "init clock error");
31873187

3188-
ret = devm_add_action_or_reset(dev, mt8188_afe_deinit_clock, (void *)afe);
3189-
if (ret)
3190-
return ret;
3191-
31923188
spin_lock_init(&afe_priv->afe_ctrl_lock);
31933189

31943190
mutex_init(&afe->irq_alloc_lock);

sound/soc/mediatek/mt8188/mt8188-audsys-clk.c

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
138138
GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "top_asm_h", 11),
139139
};
140140

141+
static void mt8188_audsys_clk_unregister(void *data)
142+
{
143+
struct mtk_base_afe *afe = data;
144+
struct mt8188_afe_private *afe_priv = afe->platform_priv;
145+
struct clk *clk;
146+
struct clk_lookup *cl;
147+
int i;
148+
149+
if (!afe_priv)
150+
return;
151+
152+
for (i = 0; i < CLK_AUD_NR_CLK; i++) {
153+
cl = afe_priv->lookup[i];
154+
if (!cl)
155+
continue;
156+
157+
clk = cl->clk;
158+
clk_unregister_gate(clk);
159+
160+
clkdev_drop(cl);
161+
}
162+
}
163+
141164
int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
142165
{
143166
struct mt8188_afe_private *afe_priv = afe->platform_priv;
@@ -179,27 +202,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
179202
afe_priv->lookup[i] = cl;
180203
}
181204

182-
return 0;
183-
}
184-
185-
void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe)
186-
{
187-
struct mt8188_afe_private *afe_priv = afe->platform_priv;
188-
struct clk *clk;
189-
struct clk_lookup *cl;
190-
int i;
191-
192-
if (!afe_priv)
193-
return;
194-
195-
for (i = 0; i < CLK_AUD_NR_CLK; i++) {
196-
cl = afe_priv->lookup[i];
197-
if (!cl)
198-
continue;
199-
200-
clk = cl->clk;
201-
clk_unregister_gate(clk);
202-
203-
clkdev_drop(cl);
204-
}
205+
return devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
205206
}

sound/soc/mediatek/mt8188/mt8188-audsys-clk.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@
1010
#define _MT8188_AUDSYS_CLK_H_
1111

1212
int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
13-
void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);
1413

1514
#endif

0 commit comments

Comments
 (0)