OSDN Git Service

ASoC: Intel: Skylake: Fix NULL ptr dereference when unloading clk dev
authorAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Mon, 17 Jun 2019 11:36:41 +0000 (13:36 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 25 Jun 2019 14:33:21 +0000 (15:33 +0100)
When driver is probed, we iterate over NHLT and check if clk entries are
present. For each such entry we call register_skl_clk and keep the
result in data->clk[].
Currently data->clk is sparsely indexed using NHLT table iterator, while
when freeing we use number of registered entries. Let's just use
data->avail_clk_cnt as index, so it can be reset back in
unregister_src_clk.

Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/skylake/skl-ssp-clk.c

index cda1b5f..5bb6e40 100644 (file)
@@ -276,10 +276,8 @@ static void unregister_parent_src_clk(struct skl_clk_parent *pclk,
 
 static void unregister_src_clk(struct skl_clk_data *dclk)
 {
-       u8 cnt = dclk->avail_clk_cnt;
-
-       while (cnt--)
-               clkdev_drop(dclk->clk[cnt]->lookup);
+       while (dclk->avail_clk_cnt--)
+               clkdev_drop(dclk->clk[dclk->avail_clk_cnt]->lookup);
 }
 
 static int skl_register_parent_clks(struct device *dev,
@@ -381,13 +379,13 @@ static int skl_clk_dev_probe(struct platform_device *pdev)
                if (clks[i].rate_cfg[0].rate == 0)
                        continue;
 
-               data->clk[i] = register_skl_clk(dev, &clks[i], clk_pdata, i);
-               if (IS_ERR(data->clk[i])) {
-                       ret = PTR_ERR(data->clk[i]);
+               data->clk[data->avail_clk_cnt] = register_skl_clk(dev,
+                               &clks[i], clk_pdata, i);
+
+               if (IS_ERR(data->clk[data->avail_clk_cnt])) {
+                       ret = PTR_ERR(data->clk[data->avail_clk_cnt++]);
                        goto err_unreg_skl_clk;
                }
-
-               data->avail_clk_cnt++;
        }
 
        platform_set_drvdata(pdev, data);