From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966515AbcKNEDy (ORCPT ); Sun, 13 Nov 2016 23:03:54 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:44997 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752073AbcKNCEM (ORCPT ); Sun, 13 Nov 2016 21:04:12 -0500 Content-Type: text/plain; charset="UTF-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 From: Ben Hutchings To: linux-kernel@vger.kernel.org, stable@vger.kernel.org CC: akpm@linux-foundation.org, "Laxminath Kasam" , "Takashi Iwai" Date: Mon, 14 Nov 2016 00:14:20 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 049/346] ALSA: pcm: Free chmap at PCM free callback, too In-Reply-To: X-SA-Exim-Connect-IP: 2a02:8011:400e:2:6f00:88c8:c921:d332 X-SA-Exim-Mail-From: ben@decadent.org.uk X-SA-Exim-Scanned: No (on shadbolt.decadent.org.uk); SAEximRunCond expanded to false Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.39-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Takashi Iwai commit a8ff48cb70835f48de5703052760312019afea55 upstream. The chmap ctls assigned to PCM streams are freed in the PCM disconnect callback. However, since the disconnect callback isn't called when the card gets freed before registering, the chmap ctls may still be left assigned. They are eventually freed together with other ctls, but it may cause an Oops at pcm_chmap_ctl_private_free(), as the function refers to the assigned PCM stream, while the PCM objects have been already freed beforehand. The fix is to free the chmap ctls also at PCM free callback, not only at PCM disconnect. Reported-by: Laxminath Kasam Signed-off-by: Takashi Iwai [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings --- sound/core/pcm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -806,6 +806,14 @@ int snd_pcm_new_internal(struct snd_card } EXPORT_SYMBOL(snd_pcm_new_internal); +static void free_chmap(struct snd_pcm_str *pstr) +{ + if (pstr->chmap_kctl) { + snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl); + pstr->chmap_kctl = NULL; + } +} + static void snd_pcm_free_stream(struct snd_pcm_str * pstr) { struct snd_pcm_substream *substream, *substream_next; @@ -828,6 +836,7 @@ static void snd_pcm_free_stream(struct s kfree(setup); } #endif + free_chmap(pstr); } static int snd_pcm_free(struct snd_pcm *pcm) @@ -1142,10 +1151,7 @@ static int snd_pcm_dev_disconnect(struct break; } snd_unregister_device(devtype, pcm->card, pcm->device); - if (pcm->streams[cidx].chmap_kctl) { - snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl); - pcm->streams[cidx].chmap_kctl = NULL; - } + free_chmap(&pcm->streams[cidx]); } mutex_unlock(&pcm->open_mutex); unlock: