summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-07-27 19:27:00 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-07-27 19:26:59 -0700
commit359db4da1586cbc0891e42f374ef59fed414dff9 (patch)
treea07857c793bf920f6af289cf5f4d583a77ca1ad9
parentea40856447043a29977f9078ede07cf2cf29f0ed (diff)
parent482c8b19a85cf0282158e98ec060f803f08e498e (diff)
Merge "ASoC: Fix freed memory access of pcm stream kctl"
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/core/pcm.c30
2 files changed, 20 insertions, 12 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index a85d45595d02..b4fe9b002512 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -160,6 +160,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
if (snd_BUG_ON(!card || !id))
return;
+ if (card->shutdown)
+ return;
read_lock(&card->ctl_files_rwlock);
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
card->mixer_oss_change_count++;
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 019751a83e25..9e4743e833be 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -849,6 +849,22 @@ int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
}
EXPORT_SYMBOL(snd_pcm_new_internal);
+static void free_pcm_kctl(struct snd_pcm_str *pstr)
+{
+ if (pstr->chmap_kctl) {
+ snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl);
+ pstr->chmap_kctl = NULL;
+ }
+ if (pstr->vol_kctl) {
+ snd_ctl_remove(pstr->pcm->card, pstr->vol_kctl);
+ pstr->vol_kctl = NULL;
+ }
+ if (pstr->usr_kctl) {
+ snd_ctl_remove(pstr->pcm->card, pstr->usr_kctl);
+ pstr->usr_kctl = NULL;
+ }
+}
+
static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
{
struct snd_pcm_substream *substream, *substream_next;
@@ -871,6 +887,7 @@ static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
kfree(setup);
}
#endif
+ free_pcm_kctl(pstr);
if (pstr->substream_count)
put_device(&pstr->dev);
}
@@ -1135,18 +1152,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
for (cidx = 0; cidx < 2; cidx++) {
if (!pcm->internal)
snd_unregister_device(&pcm->streams[cidx].dev);
- if (pcm->streams[cidx].chmap_kctl) {
- snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
- pcm->streams[cidx].chmap_kctl = NULL;
- }
- if (pcm->streams[cidx].vol_kctl) {
- snd_ctl_remove(pcm->card, pcm->streams[cidx].vol_kctl);
- pcm->streams[cidx].vol_kctl = NULL;
- }
- if (pcm->streams[cidx].usr_kctl) {
- snd_ctl_remove(pcm->card, pcm->streams[cidx].usr_kctl);
- pcm->streams[cidx].usr_kctl = NULL;
- }
+ free_pcm_kctl(&pcm->streams[cidx]);
}
mutex_unlock(&pcm->open_mutex);
mutex_unlock(&register_mutex);