lkml.org 
[lkml]   [2023]   [May]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/2] ASoC: mediatek: mt8195: fix use-after-free in driver remove path
    Date
    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: 6746cc858259 ("ASoC: mediatek: mt8195: add platform driver")
    Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
    Reviewed-by: Douglas Anderson <dianders@chromium.org>
    ---
    sound/soc/mediatek/mt8195/mt8195-afe-clk.c | 5 --
    sound/soc/mediatek/mt8195/mt8195-afe-clk.h | 1 -
    sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 4 --
    sound/soc/mediatek/mt8195/mt8195-audsys-clk.c | 47 ++++++++++---------
    sound/soc/mediatek/mt8195/mt8195-audsys-clk.h | 1 -
    5 files changed, 24 insertions(+), 34 deletions(-)

    diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
    index 9ca2cb8c8a9c..f35318ae0739 100644
    --- a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
    +++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c
    @@ -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;
    diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.h b/sound/soc/mediatek/mt8195/mt8195-afe-clk.h
    index 40663e31becd..a08c0ee6c860 100644
    --- a/sound/soc/mediatek/mt8195/mt8195-afe-clk.h
    +++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.h
    @@ -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);
    diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
    index d22cf1664d8a..a0f2012211fb 100644
    --- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
    +++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c
    @@ -3224,15 +3224,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[] = {
    diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
    index e0670e0dbd5b..38594bc3f2f7 100644
    --- a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
    +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c
    @@ -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;
    @@ -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);
    }
    diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
    index 239d31016ba7..69db2dd1c9e0 100644
    --- a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
    +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h
    @@ -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
    --
    2.18.0
    \
     
     \ /
      Last update: 2023-06-01 05:34    [W:7.992 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site