Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp1643549ybk; Mon, 11 May 2020 00:26:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwpN1sEb4zQqms7IivoFfZUdNIEUcx9R619jZLIBo6y5qtu97rSSCegDVvyHwt1k8eXGLqs X-Received: by 2002:aa7:dc49:: with SMTP id g9mr1512428edu.62.1589181992321; Mon, 11 May 2020 00:26:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589181992; cv=none; d=google.com; s=arc-20160816; b=T7UX2sLLUPWNDSs1jFS4IvHwsQl29eKUwYAbwE0wOdidOzP1/VnXTygRb9pPntzmwd 4HGgHXvA5/2XmfX3A3NBfhT+f/D60eat1Z1vp9BHpD11ApzMVDdBD1/Qs7R1ru9+Kum8 T2YSyHrzQ7DD1sa2nC9IFqP0GJ2CvPPrGp+Q/RJbetcP5vUvFpkVsrnGsLp0KNI5p0Q/ 3Ev+rAEk0Ay0YtU9Jx8CGySjZJ1fDtEB3t5RZL042AqWkmupvxT/Mlb6GYplGgn5eS/H LcE51QHpiePb6ZGHuxw4cH6Xnuz8kAoDm4MjLMrWDCk9+6VqOyDZhUQcVmg/sTUAX3rF dDmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:message-id:references :in-reply-to:subject:cc:to:from:date:content-transfer-encoding :mime-version:dkim-signature; bh=opEe6VhtUet0pRSIKtH8L9rJzKOnftJQipiXpDz646A=; b=IPJrQOvmZg+tgUUiGdxPVvm/XLSDi4dFL4xnanhCE8oxn41zS28MB35ubhZ6viyjuG vWFz6jCog9Deq3xDi4L8ESgqZWo2OF5RK3mOtI44+pE4kyFPRf67b2er8xpKjsqGiAhg w1Be8J2O/e8EEEfkT0T3F6fjrG2yG4QZaxVqxtK7sIOrY6yvzDLFJoCaCZjOEx1VveAw 4K67inUYyyaayd370l52qkvtWY4asoVnoruCqu5cUxiSlCf89iPNcv5ey0Uzr6CsNmKs sk9fsT0vYOefUDJV+amziQJmT4ONbdqfy+I5Po0Jq2IvP35X4pIwVpE+pbL8dBPbI2Lu sRuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=QLKGLOlb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ss21si3297560ejb.124.2020.05.11.00.26.09; Mon, 11 May 2020 00:26:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=QLKGLOlb; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728785AbgEKHYB (ORCPT + 99 others); Mon, 11 May 2020 03:24:01 -0400 Received: from mail26.static.mailgun.info ([104.130.122.26]:46027 "EHLO mail26.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728554AbgEKHYA (ORCPT ); Mon, 11 May 2020 03:24:00 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1589181839; h=Message-ID: References: In-Reply-To: Subject: Cc: To: From: Date: Content-Transfer-Encoding: Content-Type: MIME-Version: Sender; bh=opEe6VhtUet0pRSIKtH8L9rJzKOnftJQipiXpDz646A=; b=QLKGLOlbKNM78GLSsbf6fac5SLEPM5UqiScXY6KZ6u4FrZYrzCJ29/k/tzjzu4ChHtIhJQkf z0qbfp5lduYt8hffwKQ+NweiCLDoYND4drijOfgEYFl5CxHyFC5BAEsoQ9JD9dSrHUniuVl3 bzTxfa13ZCiclowcp9U7MQm26Wk= X-Mailgun-Sending-Ip: 104.130.122.26 X-Mailgun-Sid: WyI0MWYwYSIsICJsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnIiwgImJlOWU0YSJd Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5eb8fd8e.7f19c8556538-smtp-out-n04; Mon, 11 May 2020 07:23:58 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id B8AFDC433F2; Mon, 11 May 2020 07:23:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.codeaurora.org (localhost.localdomain [127.0.0.1]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: rananta) by smtp.codeaurora.org (Postfix) with ESMTPSA id 43C8CC433CB; Mon, 11 May 2020 07:23:58 +0000 (UTC) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Date: Mon, 11 May 2020 00:23:58 -0700 From: rananta@codeaurora.org To: Greg KH Cc: jslaby@suse.com, andrew@daynix.com, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH] tty: hvc: Fix data abort due to race in hvc_open In-Reply-To: <20200510064819.GB3400311@kroah.com> References: <20200428032601.22127-1-rananta@codeaurora.org> <20200506094851.GA2787548@kroah.com> <98bbe7afabf48d8e8fe839fdc9e836a5@codeaurora.org> <20200510064819.GB3400311@kroah.com> Message-ID: <77d889be4e0cb0e6e30f96199e2d843d@codeaurora.org> X-Sender: rananta@codeaurora.org User-Agent: Roundcube Webmail/1.3.9 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2020-05-09 23:48, Greg KH wrote: > On Sat, May 09, 2020 at 06:30:56PM -0700, rananta@codeaurora.org wrote: >> On 2020-05-06 02:48, Greg KH wrote: >> > On Mon, Apr 27, 2020 at 08:26:01PM -0700, Raghavendra Rao Ananta wrote: >> > > Potentially, hvc_open() can be called in parallel when two tasks calls >> > > open() on /dev/hvcX. In such a scenario, if the >> > > hp->ops->notifier_add() >> > > callback in the function fails, where it sets the tty->driver_data to >> > > NULL, the parallel hvc_open() can see this NULL and cause a memory >> > > abort. >> > > Hence, serialize hvc_open and check if tty->private_data is NULL >> > > before >> > > proceeding ahead. >> > > >> > > The issue can be easily reproduced by launching two tasks >> > > simultaneously >> > > that does nothing but open() and close() on /dev/hvcX. >> > > For example: >> > > $ ./simple_open_close /dev/hvc0 & ./simple_open_close /dev/hvc0 & >> > > >> > > Signed-off-by: Raghavendra Rao Ananta >> > > --- >> > > drivers/tty/hvc/hvc_console.c | 16 ++++++++++++++-- >> > > 1 file changed, 14 insertions(+), 2 deletions(-) >> > > >> > > diff --git a/drivers/tty/hvc/hvc_console.c >> > > b/drivers/tty/hvc/hvc_console.c >> > > index 436cc51c92c3..ebe26fe5ac09 100644 >> > > --- a/drivers/tty/hvc/hvc_console.c >> > > +++ b/drivers/tty/hvc/hvc_console.c >> > > @@ -75,6 +75,8 @@ static LIST_HEAD(hvc_structs); >> > > */ >> > > static DEFINE_MUTEX(hvc_structs_mutex); >> > > >> > > +/* Mutex to serialize hvc_open */ >> > > +static DEFINE_MUTEX(hvc_open_mutex); >> > > /* >> > > * This value is used to assign a tty->index value to a hvc_struct >> > > based >> > > * upon order of exposure via hvc_probe(), when we can not match it >> > > to >> > > @@ -346,16 +348,24 @@ static int hvc_install(struct tty_driver >> > > *driver, struct tty_struct *tty) >> > > */ >> > > static int hvc_open(struct tty_struct *tty, struct file * filp) >> > > { >> > > - struct hvc_struct *hp = tty->driver_data; >> > > + struct hvc_struct *hp; >> > > unsigned long flags; >> > > int rc = 0; >> > > >> > > + mutex_lock(&hvc_open_mutex); >> > > + >> > > + hp = tty->driver_data; >> > > + if (!hp) { >> > > + rc = -EIO; >> > > + goto out; >> > > + } >> > > + >> > > spin_lock_irqsave(&hp->port.lock, flags); >> > > /* Check and then increment for fast path open. */ >> > > if (hp->port.count++ > 0) { >> > > spin_unlock_irqrestore(&hp->port.lock, flags); >> > > hvc_kick(); >> > > - return 0; >> > > + goto out; >> > > } /* else count == 0 */ >> > > spin_unlock_irqrestore(&hp->port.lock, flags); >> > >> > Wait, why isn't this driver just calling tty_port_open() instead of >> > trying to open-code all of this? >> > >> > Keeping a single mutext for open will not protect it from close, it will >> > just slow things down a bit. There should already be a tty lock held by >> > the tty core for open() to keep it from racing things, right? >> The tty lock should have been held, but not likely across ->install() >> and >> ->open() callbacks, thus resulting in a race between hvc_install() and >> hvc_open(), > > How? The tty lock is held in install, and should not conflict with > open(), otherwise, we would be seeing this happen in all tty drivers, > right? > Well, I was expecting the same, but IIRC, I see that the open() was being called in parallel for the same device node. Is it expected that the tty core would allow only one thread to access the dev-node, while blocking the other, or is it the client driver's responsibility to handle the exclusiveness? >> where hvc_install() sets a data and the hvc_open() clears it. >> hvc_open() >> doesn't >> check if the data was set to NULL and proceeds. > > What data is being set that hvc_open is checking? hvc_install sets tty->private_data to hp, while hvc_open sets it to NULL (in one of the paths). > > And you are not grabbing a lock in your install callback, you are only > serializing your open call here, I don't see how this is fixing > anything > other than perhaps slowing down your codepaths. Basically, my intention was to add a NULL check before accessing *hp in open(). The intention of the lock was to protect against this check. If the tty layer would have taken care of this, then perhaps there won't be a need to check for NULL. > > As an arument why this isn't correct, can you answer why this same type > of change wouldn't be required for all tty drivers in the tree? > I agree, that if it's already taken care by the tty-core, we don't need it here. Correct me if I'm wrong, but looks like the tty layer is allowing parallel accesses to open(), > thanks, > > greg k-h