Skip to content

Commit

Permalink
ASoC: mediatek: fix use-after-free in driver remove
Browse files Browse the repository at this point in the history
Merge series from Trevor Wu <trevor.wu@mediatek.com>:

These patches concern modifications made in mt8186[1]. The clock
unregistration mechanism used in mt8188 and mt8195 is similar with
mt8186, resulting in the same problem existing within the driver.
Therefore, the solution has also been applied to these two platforms.

[1] https://lore.kernel.org/all/20230511092437.1.I31cceffc8c45bb1af16eb613e197b3df92cdc19e@changeid/
  • Loading branch information
Mark Brown committed Jun 1, 2023
2 parents 524306c + dc93f0d commit ce78930
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 70 deletions.
7 changes: 0 additions & 7 deletions sound/soc/mediatek/mt8188/mt8188-afe-clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,13 +418,6 @@ int mt8188_afe_init_clock(struct mtk_base_afe *afe)
return 0;
}

void mt8188_afe_deinit_clock(void *priv)
{
struct mtk_base_afe *afe = priv;

mt8188_audsys_clk_unregister(afe);
}

int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
{
int ret;
Expand Down
1 change: 0 additions & 1 deletion sound/soc/mediatek/mt8188/mt8188-afe-clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ int mt8188_afe_get_mclk_source_clk_id(int sel);
int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
int mt8188_afe_get_default_mclk_source_by_rate(int rate);
int mt8188_afe_init_clock(struct mtk_base_afe *afe);
void mt8188_afe_deinit_clock(void *priv);
int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
Expand Down
4 changes: 0 additions & 4 deletions sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3185,10 +3185,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "init clock error");

ret = devm_add_action_or_reset(dev, mt8188_afe_deinit_clock, (void *)afe);
if (ret)
return ret;

spin_lock_init(&afe_priv->afe_ctrl_lock);

mutex_init(&afe->irq_alloc_lock);
Expand Down
47 changes: 24 additions & 23 deletions sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "top_asm_h", 11),
};

static void mt8188_audsys_clk_unregister(void *data)
{
struct mtk_base_afe *afe = data;
struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
int i;

if (!afe_priv)
return;

for (i = 0; i < CLK_AUD_NR_CLK; i++) {
cl = afe_priv->lookup[i];
if (!cl)
continue;

clk = cl->clk;
clk_unregister_gate(clk);

clkdev_drop(cl);
}
}

int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
{
struct mt8188_afe_private *afe_priv = afe->platform_priv;
Expand Down Expand Up @@ -179,27 +202,5 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
afe_priv->lookup[i] = cl;
}

return 0;
}

void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe)
{
struct mt8188_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
int i;

if (!afe_priv)
return;

for (i = 0; i < CLK_AUD_NR_CLK; i++) {
cl = afe_priv->lookup[i];
if (!cl)
continue;

clk = cl->clk;
clk_unregister_gate(clk);

clkdev_drop(cl);
}
return devm_add_action_or_reset(afe->dev, mt8188_audsys_clk_unregister, afe);
}
1 change: 0 additions & 1 deletion sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@
#define _MT8188_AUDSYS_CLK_H_

int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);

#endif
5 changes: 0 additions & 5 deletions sound/soc/mediatek/mt8195/mt8195-afe-clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -410,11 +410,6 @@ int mt8195_afe_init_clock(struct mtk_base_afe *afe)
return 0;
}

void mt8195_afe_deinit_clock(struct mtk_base_afe *afe)
{
mt8195_audsys_clk_unregister(afe);
}

int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
{
int ret;
Expand Down
1 change: 0 additions & 1 deletion sound/soc/mediatek/mt8195/mt8195-afe-clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ int mt8195_afe_get_mclk_source_clk_id(int sel);
int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
int mt8195_afe_get_default_mclk_source_by_rate(int rate);
int mt8195_afe_init_clock(struct mtk_base_afe *afe);
void mt8195_afe_deinit_clock(struct mtk_base_afe *afe);
int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk);
Expand Down
4 changes: 0 additions & 4 deletions sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3255,15 +3255,11 @@ static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev)

static void mt8195_afe_pcm_dev_remove(struct platform_device *pdev)
{
struct mtk_base_afe *afe = platform_get_drvdata(pdev);

snd_soc_unregister_component(&pdev->dev);

pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mt8195_afe_runtime_suspend(&pdev->dev);

mt8195_afe_deinit_clock(afe);
}

static const struct of_device_id mt8195_afe_pcm_dt_match[] = {
Expand Down
47 changes: 24 additions & 23 deletions sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,29 @@ static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "top_asm_h", 19),
};

static void mt8195_audsys_clk_unregister(void *data)
{
struct mtk_base_afe *afe = data;
struct mt8195_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
int i;

if (!afe_priv)
return;

for (i = 0; i < CLK_AUD_NR_CLK; i++) {
cl = afe_priv->lookup[i];
if (!cl)
continue;

clk = cl->clk;
clk_unregister_gate(clk);

clkdev_drop(cl);
}
}

int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
{
struct mt8195_afe_private *afe_priv = afe->platform_priv;
Expand Down Expand Up @@ -188,27 +211,5 @@ int mt8195_audsys_clk_register(struct mtk_base_afe *afe)
afe_priv->lookup[i] = cl;
}

return 0;
}

void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe)
{
struct mt8195_afe_private *afe_priv = afe->platform_priv;
struct clk *clk;
struct clk_lookup *cl;
int i;

if (!afe_priv)
return;

for (i = 0; i < CLK_AUD_NR_CLK; i++) {
cl = afe_priv->lookup[i];
if (!cl)
continue;

clk = cl->clk;
clk_unregister_gate(clk);

clkdev_drop(cl);
}
return devm_add_action_or_reset(afe->dev, mt8195_audsys_clk_unregister, afe);
}
1 change: 0 additions & 1 deletion sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@
#define _MT8195_AUDSYS_CLK_H_

int mt8195_audsys_clk_register(struct mtk_base_afe *afe);
void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe);

#endif

0 comments on commit ce78930

Please sign in to comment.