Received: by 10.223.185.116 with SMTP id b49csp6396646wrg; Wed, 28 Feb 2018 08:43:52 -0800 (PST) X-Google-Smtp-Source: AG47ELveAsRjiELCBhOU4pujClteu6h25kmvw9SU0FWfl0F3Ic58aEnMigH0uKbs5Vun34R/Qv39 X-Received: by 2002:a17:902:309:: with SMTP id 9-v6mr5765617pld.63.1519836232120; Wed, 28 Feb 2018 08:43:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519836232; cv=none; d=google.com; s=arc-20160816; b=QxThx8GKp98irWwZWTg/15lB4lF7C+jhh9DQRSLNe5JsBhG/CQz3Ymt/x80VNmgSFo WfgLdW+yRaqLwlak8ttZCG141VoLsxIiOpyDUnXdZ9iR2sVdT0dwCR5Vfm3PDDsZUiUQ 4hEiy76grYVYqDqU210nNCOw7vU8fNlUWrEMeSeIynPVuQwmKQZtlJtq/z2xoluAclNB aq6ol6Gt4ZwnquUmaLtnkg+DfUobN4llgIeep0JxVs2zUPiYsdCGzsDoazjUcju3ODsw 1TXCA5/TlG7y83JA3Du/uxd0RWFU2oaxXUD4aJ0dGX5PQjuShHiU7Q0sE+/B/7xHMD0c Ik2A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:subject:message-id:date:cc:to :from:mime-version:content-transfer-encoding:content-disposition :arc-authentication-results; bh=CeBUPzw9YO+I0hw0CQZ2xn+LLX1EE/rX9WP5IiqE33Y=; b=n6idRxqH871TAkUEISvjnoah8hQtgC9lN8f12EA0OQHh7u8wfYORjUI5AeXA9cYPiE fhNXKXINqeW5C3vW8q+S2rGPqwF1l8+S9DGekA+5KF7U8MVuuPPGWnVV9gs9lbL7DNq7 EXkhiSaGybJtLNhzausQvTd2wFV/u9Ik8VPUE2AP4+Lt6I0cHJfUIMVyRKGfD18TLrkS F9r1wBUeJQ1QqMRTG2SrgMRf57xgEJuRiEq4P541Ygcvvganb8Ouc1ClSsLolypjUd+g EmRSCyQEvyGnEOJy4uVVJsNl7I4KrOs+IutcOe3C91tHOsUVMJDoIk+twGhij5qkC4qh PhmA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a12si1217206pgv.672.2018.02.28.08.43.37; Wed, 28 Feb 2018 08:43:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932801AbeB1QDR (ORCPT + 99 others); Wed, 28 Feb 2018 11:03:17 -0500 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:34749 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932699AbeB1QDO (ORCPT ); Wed, 28 Feb 2018 11:03:14 -0500 Received: from [2a02:8011:400e:2:6f00:88c8:c921:d332] (helo=deadeye) by shadbolt.decadent.org.uk with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1er3Yj-0006Xh-Jd; Wed, 28 Feb 2018 15:22:22 +0000 Received: from ben by deadeye with local (Exim 4.90_1) (envelope-from ) id 1er3Yi-0000CV-NQ; Wed, 28 Feb 2018 15:22:20 +0000 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, "Takashi Iwai" Date: Wed, 28 Feb 2018 15:20:18 +0000 Message-ID: X-Mailer: LinuxStableQueue (scripts by bwh) Subject: [PATCH 3.16 175/254] ALSA: aloop: Release cable upon open error path 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 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.55-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Takashi Iwai commit 9685347aa0a5c2869058ca6ab79fd8e93084a67f upstream. The aloop runtime object and its assignment in the cable are left even when opening a substream fails. This doesn't mean any memory leak, but it still keeps the invalid pointer that may be referred by the another side of the cable spontaneously, which is a potential Oops cause. Clean up the cable assignment and the empty cable upon the error path properly. Fixes: 597603d615d2 ("ALSA: introduce the snd-aloop module for the PCM loopback") Signed-off-by: Takashi Iwai Signed-off-by: Ben Hutchings --- sound/drivers/aloop.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -659,12 +659,31 @@ static int rule_channels(struct snd_pcm_ return snd_interval_refine(hw_param_interval(params, rule->var), &t); } +static void free_cable(struct snd_pcm_substream *substream) +{ + struct loopback *loopback = substream->private_data; + int dev = get_cable_index(substream); + struct loopback_cable *cable; + + cable = loopback->cables[substream->number][dev]; + if (!cable) + return; + if (cable->streams[!substream->stream]) { + /* other stream is still alive */ + cable->streams[substream->stream] = NULL; + } else { + /* free the cable */ + loopback->cables[substream->number][dev] = NULL; + kfree(cable); + } +} + static int loopback_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct loopback *loopback = substream->private_data; struct loopback_pcm *dpcm; - struct loopback_cable *cable; + struct loopback_cable *cable = NULL; int err = 0; int dev = get_cable_index(substream); @@ -683,7 +702,6 @@ static int loopback_open(struct snd_pcm_ if (!cable) { cable = kzalloc(sizeof(*cable), GFP_KERNEL); if (!cable) { - kfree(dpcm); err = -ENOMEM; goto unlock; } @@ -725,6 +743,10 @@ static int loopback_open(struct snd_pcm_ else runtime->hw = cable->hw; unlock: + if (err < 0) { + free_cable(substream); + kfree(dpcm); + } mutex_unlock(&loopback->cable_lock); return err; } @@ -733,20 +755,10 @@ static int loopback_close(struct snd_pcm { struct loopback *loopback = substream->private_data; struct loopback_pcm *dpcm = substream->runtime->private_data; - struct loopback_cable *cable; - int dev = get_cable_index(substream); loopback_timer_stop(dpcm); mutex_lock(&loopback->cable_lock); - cable = loopback->cables[substream->number][dev]; - if (cable->streams[!substream->stream]) { - /* other stream is still alive */ - cable->streams[substream->stream] = NULL; - } else { - /* free the cable */ - loopback->cables[substream->number][dev] = NULL; - kfree(cable); - } + free_cable(substream); mutex_unlock(&loopback->cable_lock); return 0; }