Skip to content

Commit dc93f0d

Browse files
wenliangwubroonie
authored andcommitted
ASoC: mediatek: mt8195: fix use-after-free in driver remove path
During mt8195_afe_init_clock(), mt8195_audsys_clk_register() was called followed by several other devm functions. At mt8195_afe_deinit_clock() located at mt8195_afe_pcm_dev_remove(), mt8195_audsys_clk_unregister() was called. However, there was an issue with the order in which these functions were called. Specifically, the remove callback of platform_driver was called before devres released the resource, resulting in a use-after-free issue during remove time. At probe time, the order of calls was: 1. mt8195_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. mt8195_audsys_clk_unregister 3. free afe_priv->clk[i] 2. free afe_priv->clk To resolve the problem, we can utilize devm_add_action_or_reset() in mt8195_audsys_clk_register() so that the remove order can be changed to 3->2->1. Fixes: 6746cc8 ("ASoC: mediatek: mt8195: add platform driver") 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-3-trevor.wu@mediatek.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent fd67a7a commit dc93f0d

File tree

5 files changed

+24
-34
lines changed

5 files changed

+24
-34
lines changed

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,6 @@ int mt8195_afe_init_clock(struct mtk_base_afe *afe)
410410
return 0;
411411
}
412412

413-
void mt8195_afe_deinit_clock(struct mtk_base_afe *afe)
414-
{
415-
mt8195_audsys_clk_unregister(afe);
416-
}
417-
418413
int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
419414
{
420415
int ret;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ int mt8195_afe_get_mclk_source_clk_id(int sel);
101101
int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
102102
int mt8195_afe_get_default_mclk_source_by_rate(int rate);
103103
int mt8195_afe_init_clock(struct mtk_base_afe *afe);
104-
void mt8195_afe_deinit_clock(struct mtk_base_afe *afe);
105104
int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
106105
void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
107106
int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk);

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3255,15 +3255,11 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev)
32553255

32563256
static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
32573257
{
3258-
struct mtk_base_afe *afe = platform_get_drvdata(pdev);
3259-
32603258
snd_soc_unregister_component(&pdev->dev);
32613259

32623260
pm_runtime_disable(&pdev->dev);
32633261
if (!pm_runtime_status_suspended(&pdev->dev))
32643262
mt8195_afe_runtime_suspend(&pdev->dev);
3265-
3266-
mt8195_afe_deinit_clock(afe);
32673263
}
32683264

32693265
static const struct of_device_id mt8195_afe_pcm_dt_match[] = {

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

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
148148
GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "top_asm_h", 19),
149149
};
150150

151+
static void mt8195_audsys_clk_unregister(void *data)
152+
{
153+
struct mtk_base_afe *afe = data;
154+
struct mt8195_afe_private *afe_priv = afe->platform_priv;
155+
struct clk *clk;
156+
struct clk_lookup *cl;
157+
int i;
158+
159+
if (!afe_priv)
160+
return;
161+
162+
for (i = 0; i < CLK_AUD_NR_CLK; i++) {
163+
cl = afe_priv->lookup[i];
164+
if (!cl)
165+
continue;
166+
167+
clk = cl->clk;
168+
clk_unregister_gate(clk);
169+
170+
clkdev_drop(cl);
171+
}
172+
}
173+
151174
int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
152175
{
153176
struct mt8195_afe_private *afe_priv = afe->platform_priv;
@@ -188,27 +211,5 @@ int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
188211
afe_priv->lookup[i] = cl;
189212
}
190213

191-
return 0;
192-
}
193-
194-
void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
195-
{
196-
struct mt8195_afe_private *afe_priv = afe->platform_priv;
197-
struct clk *clk;
198-
struct clk_lookup *cl;
199-
int i;
200-
201-
if (!afe_priv)
202-
return;
203-
204-
for (i = 0; i < CLK_AUD_NR_CLK; i++) {
205-
cl = afe_priv->lookup[i];
206-
if (!cl)
207-
continue;
208-
209-
clk = cl->clk;
210-
clk_unregister_gate(clk);
211-
212-
clkdev_drop(cl);
213-
}
214+
return devm_add_action_or_reset(afe->dev, mt8195_audsys_clk_unregister, afe);
214215
}

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

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

1212
int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
13-
void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);
1413

1514
#endif

0 commit comments

Comments
 (0)