1 From 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d Mon Sep 17 00:00:00 2001
2 From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
3 Date: Tue, 27 Mar 2018 12:04:04 +0100
4 Subject: ASoC: topology: Fix kcontrol name string handling
6 From: Liam Girdwood <liam.r.girdwood@linux.intel.com>
8 commit 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d upstream.
10 Fix the topology kcontrol string handling so that string pointer
11 references are strdup()ed instead of being copied. This fixes issues
12 with kcontrol templates on the stack or ones that are freed. Remember
13 and free the strings too when topology is unloaded.
15 Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
16 Signed-off-by: Mark Brown <broonie@kernel.org>
17 Cc: stable@vger.kernel.org
18 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21 sound/soc/soc-topology.c | 23 ++++++++++++++++++-----
22 1 file changed, 18 insertions(+), 5 deletions(-)
24 --- a/sound/soc/soc-topology.c
25 +++ b/sound/soc/soc-topology.c
26 @@ -523,6 +523,7 @@ static void remove_widget(struct snd_soc
27 kfree(se->dobj.control.dtexts[j]);
30 + kfree(w->kcontrol_news[i].name);
32 kfree(w->kcontrol_news);
34 @@ -540,6 +541,7 @@ static void remove_widget(struct snd_soc
36 kfree((void *)kcontrol->private_value);
37 snd_ctl_remove(card, kcontrol);
38 + kfree(w->kcontrol_news[i].name);
40 kfree(w->kcontrol_news);
42 @@ -1233,7 +1235,9 @@ static struct snd_kcontrol_new *soc_tplg
43 dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at %d\n",
46 - kc[i].name = mc->hdr.name;
47 + kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL);
48 + if (kc[i].name == NULL)
50 kc[i].private_value = (long)sm;
51 kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
52 kc[i].access = mc->hdr.access;
53 @@ -1278,8 +1282,10 @@ static struct snd_kcontrol_new *soc_tplg
57 - for (--i; i >= 0; i--)
58 + for (--i; i >= 0; i--) {
59 kfree((void *)kc[i].private_value);
65 @@ -1310,7 +1316,9 @@ static struct snd_kcontrol_new *soc_tplg
66 dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n",
69 - kc[i].name = ec->hdr.name;
70 + kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
71 + if (kc[i].name == NULL)
73 kc[i].private_value = (long)se;
74 kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
75 kc[i].access = ec->hdr.access;
76 @@ -1386,6 +1394,7 @@ err_se:
77 kfree(se->dobj.control.dtexts[j]);
84 @@ -1424,7 +1433,9 @@ static struct snd_kcontrol_new *soc_tplg
85 "ASoC: adding bytes kcontrol %s with access 0x%x\n",
86 be->hdr.name, be->hdr.access);
88 - kc[i].name = be->hdr.name;
89 + kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
90 + if (kc[i].name == NULL)
92 kc[i].private_value = (long)sbe;
93 kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
94 kc[i].access = be->hdr.access;
95 @@ -1454,8 +1465,10 @@ static struct snd_kcontrol_new *soc_tplg
99 - for (--i; i >= 0; i--)
100 + for (--i; i >= 0; i--) {
101 kfree((void *)kc[i].private_value);