OSDN Git Service

ASoC: soc-dapm.c: fixup snd_soc_dapm_new_control_unlocked() error handling
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Mon, 5 Sep 2022 23:17:57 +0000 (23:17 +0000)
committerMark Brown <broonie@kernel.org>
Wed, 7 Sep 2022 11:44:31 +0000 (12:44 +0100)
Current snd_soc_dapm_new_control_unlocked() error handling is wrong.
It is using "goto request_failed" (A), but error message is using
"w->name" (B) which is not yet created in such timing.

snd_soc_dapm_new_control_unlocked(xxx)
{
...
switch (w->id) {
case xxx:
...
if (IS_ERR(...)) {
ret = PTR_ERR(...);
(A) goto request_failed;
}
...
}

prefix = soc_dapm_prefix(...);
if (prefix)
(B) w->name = kasprintf(...);
else
(B) w->name = kstrdup_const(...);
...

(A) request_failed:
if (ret != -EPROBE_DEFER)
(B) dev_err(..., w->name, ...);

return ...;
}

we can create "w->name" at beginning of this function.
In such case, we need to call kfree_const(w->name) at error case.
This patch do these.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87wnah8l7e.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/soc-dapm.c

index 0292439..76615d5 100644 (file)
@@ -3630,10 +3630,18 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
        enum snd_soc_dapm_direction dir;
        struct snd_soc_dapm_widget *w;
        const char *prefix;
-       int ret;
+       int ret = -ENOMEM;
 
        if ((w = dapm_cnew_widget(widget)) == NULL)
-               return ERR_PTR(-ENOMEM);
+               goto cnew_failed;
+
+       prefix = soc_dapm_prefix(dapm);
+       if (prefix)
+               w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name);
+       else
+               w->name = kstrdup_const(widget->name, GFP_KERNEL);
+       if (!w->name)
+               goto name_failed;
 
        switch (w->id) {
        case snd_soc_dapm_regulator_supply:
@@ -3672,17 +3680,6 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,
                break;
        }
 
-       prefix = soc_dapm_prefix(dapm);
-       if (prefix)
-               w->name = kasprintf(GFP_KERNEL, "%s %s", prefix, widget->name);
-       else
-               w->name = kstrdup_const(widget->name, GFP_KERNEL);
-       if (w->name == NULL) {
-               kfree_const(w->sname);
-               kfree(w);
-               return ERR_PTR(-ENOMEM);
-       }
-
        switch (w->id) {
        case snd_soc_dapm_mic:
                w->is_ep = SND_SOC_DAPM_EP_SOURCE;
@@ -3770,9 +3767,11 @@ request_failed:
        if (ret != -EPROBE_DEFER)
                dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n",
                        w->name, ret);
-
+       kfree_const(w->name);
+name_failed:
        kfree_const(w->sname);
        kfree(w);
+cnew_failed:
        return ERR_PTR(ret);
 }