ASoC: topology: Fix kcontrol name string handling

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 <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org
This commit is contained in:
Liam Girdwood 2018-03-27 12:04:04 +01:00 committed by Mark Brown
parent 7928b2cbe5
commit 267e2c6fd7
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
1 changed files with 18 additions and 5 deletions

View File

@ -523,6 +523,7 @@ static void remove_widget(struct snd_soc_component *comp,
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_component *comp,
*/
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_dapm_widget_dmixer_create(
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_dapm_widget_dmixer_create(
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_dapm_widget_denum_create(
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_dapm_widget_dbytes_create(
"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_dapm_widget_dbytes_create(
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;