diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-07-27 19:27:00 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-07-27 19:26:59 -0700 |
| commit | 359db4da1586cbc0891e42f374ef59fed414dff9 (patch) | |
| tree | a07857c793bf920f6af289cf5f4d583a77ca1ad9 | |
| parent | ea40856447043a29977f9078ede07cf2cf29f0ed (diff) | |
| parent | 482c8b19a85cf0282158e98ec060f803f08e498e (diff) | |
Merge "ASoC: Fix freed memory access of pcm stream kctl"
| -rw-r--r-- | sound/core/control.c | 2 | ||||
| -rw-r--r-- | sound/core/pcm.c | 30 |
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(®ister_mutex); |
