]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
ASoC: qcom: Fix of-node refcount unbalance in apq8016_sbc_parse_of()
authorTakashi Iwai <tiwai@suse.de>
Tue, 19 Feb 2019 15:46:50 +0000 (16:46 +0100)
committerKhalid Elmously <khalid.elmously@canonical.com>
Fri, 14 Feb 2020 05:29:37 +0000 (00:29 -0500)
BugLink: https://bugs.launchpad.net/bugs/1863019
[ Upstream commit 8d1667200850f8753c0265fa4bd25c9a6e5f94ce ]

The apq8016 driver leaves the of-node refcount at aborting from the
loop of for_each_child_of_node() in the error path.  Not only the
iterator node of for_each_child_of_node(), the children nodes referred
from it for codec and cpu have to be properly unreferenced.

Fixes: bdb052e81f62 ("ASoC: qcom: add apq8016 sound card support")
Cc: Patrick Lai <plai@codeaurora.org>
Cc: Banajit Goswami <bgoswami@codeaurora.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
sound/soc/qcom/apq8016_sbc.c

index d49adc822a110ed2a9b61f1916570ed70065a3fd..8e6b88d68ca6ca981cc4d5bd5cd818f33a614b16 100644 (file)
@@ -163,41 +163,52 @@ static struct apq8016_sbc_data *apq8016_sbc_parse_of(struct snd_soc_card *card)
 
                if (!cpu || !codec) {
                        dev_err(dev, "Can't find cpu/codec DT node\n");
-                       return ERR_PTR(-EINVAL);
+                       ret = -EINVAL;
+                       goto error;
                }
 
                link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
                if (!link->cpu_of_node) {
                        dev_err(card->dev, "error getting cpu phandle\n");
-                       return ERR_PTR(-EINVAL);
+                       ret = -EINVAL;
+                       goto error;
                }
 
                ret = snd_soc_of_get_dai_name(cpu, &link->cpu_dai_name);
                if (ret) {
                        dev_err(card->dev, "error getting cpu dai name\n");
-                       return ERR_PTR(ret);
+                       goto error;
                }
 
                ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
 
                if (ret < 0) {
                        dev_err(card->dev, "error getting codec dai name\n");
-                       return ERR_PTR(ret);
+                       goto error;
                }
 
                link->platform_of_node = link->cpu_of_node;
                ret = of_property_read_string(np, "link-name", &link->name);
                if (ret) {
                        dev_err(card->dev, "error getting codec dai_link name\n");
-                       return ERR_PTR(ret);
+                       goto error;
                }
 
                link->stream_name = link->name;
                link->init = apq8016_sbc_dai_init;
                link++;
+
+               of_node_put(cpu);
+               of_node_put(codec);
        }
 
        return data;
+
+ error:
+       of_node_put(np);
+       of_node_put(cpu);
+       of_node_put(codec);
+       return ERR_PTR(ret);
 }
 
 static const struct snd_soc_dapm_widget apq8016_sbc_dapm_widgets[] = {