4.16-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Liam Girdwood <[email protected]>

commit 267e2c6fd7ca3d4076d20f9d52d49dc91addfe9d upstream.

Fix the topology kcontrol string handling so that string pointer
references are strdup()ed instead of being copied. This fixes issues
with kcontrol templates on the stack or ones that are freed. Remember
and free the strings too when topology is unloaded.

Signed-off-by: Liam Girdwood <[email protected]>
Signed-off-by: Mark Brown <[email protected]>
Cc: [email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 sound/soc/soc-topology.c |   23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

--- a/sound/soc/soc-topology.c
+++ b/sound/soc/soc-topology.c
@@ -523,6 +523,7 @@ static void remove_widget(struct snd_soc
                                kfree(se->dobj.control.dtexts[j]);
 
                        kfree(se);
+                       kfree(w->kcontrol_news[i].name);
                }
                kfree(w->kcontrol_news);
        } else {
@@ -540,6 +541,7 @@ static void remove_widget(struct snd_soc
                         */
                        kfree((void *)kcontrol->private_value);
                        snd_ctl_remove(card, kcontrol);
+                       kfree(w->kcontrol_news[i].name);
                }
                kfree(w->kcontrol_news);
        }
@@ -1233,7 +1235,9 @@ static struct snd_kcontrol_new *soc_tplg
                dev_dbg(tplg->dev, " adding DAPM widget mixer control %s at 
%d\n",
                        mc->hdr.name, i);
 
-               kc[i].name = mc->hdr.name;
+               kc[i].name = kstrdup(mc->hdr.name, GFP_KERNEL);
+               if (kc[i].name == NULL)
+                       goto err_str;
                kc[i].private_value = (long)sm;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = mc->hdr.access;
@@ -1278,8 +1282,10 @@ static struct snd_kcontrol_new *soc_tplg
 err_str:
        kfree(sm);
 err:
-       for (--i; i >= 0; i--)
+       for (--i; i >= 0; i--) {
                kfree((void *)kc[i].private_value);
+               kfree(kc[i].name);
+       }
        kfree(kc);
        return NULL;
 }
@@ -1310,7 +1316,9 @@ static struct snd_kcontrol_new *soc_tplg
                dev_dbg(tplg->dev, " adding DAPM widget enum control %s\n",
                        ec->hdr.name);
 
-               kc[i].name = ec->hdr.name;
+               kc[i].name = kstrdup(ec->hdr.name, GFP_KERNEL);
+               if (kc[i].name == NULL)
+                       goto err_se;
                kc[i].private_value = (long)se;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = ec->hdr.access;
@@ -1386,6 +1394,7 @@ err_se:
                        kfree(se->dobj.control.dtexts[j]);
 
                kfree(se);
+               kfree(kc[i].name);
        }
 err:
        kfree(kc);
@@ -1424,7 +1433,9 @@ static struct snd_kcontrol_new *soc_tplg
                        "ASoC: adding bytes kcontrol %s with access 0x%x\n",
                        be->hdr.name, be->hdr.access);
 
-               kc[i].name = be->hdr.name;
+               kc[i].name = kstrdup(be->hdr.name, GFP_KERNEL);
+               if (kc[i].name == NULL)
+                       goto err;
                kc[i].private_value = (long)sbe;
                kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
                kc[i].access = be->hdr.access;
@@ -1454,8 +1465,10 @@ static struct snd_kcontrol_new *soc_tplg
        return kc;
 
 err:
-       for (--i; i >= 0; i--)
+       for (--i; i >= 0; i--) {
                kfree((void *)kc[i].private_value);
+               kfree(kc[i].name);
+       }
 
        kfree(kc);
        return NULL;


Reply via email to