ASoC: SOF: topology: Fix error handling in sof_widget_ready()
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Tue, 7 Mar 2023 11:48:15 +0000 (13:48 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 7 Mar 2023 13:57:58 +0000 (13:57 +0000)
Fix the error paths in sof_widget_ready() to free all allocated memory
and prevent memory leaks.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230307114815.4909-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/topology.c

index 4a62ccc..9f3a038 100644 (file)
@@ -1388,14 +1388,15 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
        if (ret < 0) {
                dev_err(scomp->dev, "failed to parse component pin tokens for %s\n",
                        w->name);
-               return ret;
+               goto widget_free;
        }
 
        if (swidget->num_sink_pins > SOF_WIDGET_MAX_NUM_PINS ||
            swidget->num_source_pins > SOF_WIDGET_MAX_NUM_PINS) {
                dev_err(scomp->dev, "invalid pins for %s: [sink: %d, src: %d]\n",
                        swidget->widget->name, swidget->num_sink_pins, swidget->num_source_pins);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto widget_free;
        }
 
        if (swidget->num_sink_pins > 1) {
@@ -1404,7 +1405,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                if (ret < 0) {
                        dev_err(scomp->dev, "failed to parse sink pin binding for %s\n",
                                w->name);
-                       return ret;
+                       goto widget_free;
                }
        }
 
@@ -1414,7 +1415,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                if (ret < 0) {
                        dev_err(scomp->dev, "failed to parse source pin binding for %s\n",
                                w->name);
-                       return ret;
+                       goto widget_free;
                }
        }
 
@@ -1436,9 +1437,8 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
        case snd_soc_dapm_dai_out:
                dai = kzalloc(sizeof(*dai), GFP_KERNEL);
                if (!dai) {
-                       kfree(swidget);
-                       return -ENOMEM;
-
+                       ret = -ENOMEM;
+                       goto widget_free;
                }
 
                ret = sof_widget_parse_tokens(scomp, swidget, tw, token_list, token_list_size);
@@ -1496,8 +1496,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                        tw->shift, swidget->id, tw->name,
                        strnlen(tw->sname, SNDRV_CTL_ELEM_ID_NAME_MAXLEN) > 0
                                ? tw->sname : "none");
-               kfree(swidget);
-               return ret;
+               goto widget_free;
        }
 
        if (sof_debug_check_flag(SOF_DBG_DISABLE_MULTICORE)) {
@@ -1518,10 +1517,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
                        if (ret) {
                                dev_err(scomp->dev, "widget event binding failed for %s\n",
                                        swidget->widget->name);
-                               kfree(swidget->private);
-                               kfree(swidget->tuples);
-                               kfree(swidget);
-                               return ret;
+                               goto free;
                        }
                }
        }
@@ -1532,10 +1528,8 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
 
                spipe = kzalloc(sizeof(*spipe), GFP_KERNEL);
                if (!spipe) {
-                       kfree(swidget->private);
-                       kfree(swidget->tuples);
-                       kfree(swidget);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto free;
                }
 
                spipe->pipe_widget = swidget;
@@ -1546,6 +1540,12 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index,
        w->dobj.private = swidget;
        list_add(&swidget->list, &sdev->widget_list);
        return ret;
+free:
+       kfree(swidget->private);
+       kfree(swidget->tuples);
+widget_free:
+       kfree(swidget);
+       return ret;
 }
 
 static int sof_route_unload(struct snd_soc_component *scomp,