diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2022-09-06 01:17:57 +0200 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2022-09-07 13:44:31 +0200 |
commit | 3caac759681eeb31ac80e3cc14b972680c8bde54 (patch) | |
tree | 9c804cd07a2e46c7fcbca86c42e4f2007e0dff87 /sound/soc/soc-dapm.c | |
parent | ASoC: soc-dapm.c: don't use WARN_ON() at snd_soc_dai_link_event_pre_pmu() (diff) | |
download | linux-3caac759681eeb31ac80e3cc14b972680c8bde54.tar.xz linux-3caac759681eeb31ac80e3cc14b972680c8bde54.zip |
ASoC: soc-dapm.c: fixup snd_soc_dapm_new_control_unlocked() error handling
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>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r-- | sound/soc/soc-dapm.c | 27 |
1 files changed, 13 insertions, 14 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 02924395ed86..76615d59e2b6 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -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); } |