Received: by 2002:a25:683:0:0:0:0:0 with SMTP id 125csp729174ybg; Tue, 9 Jun 2020 11:16:59 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxGJxYstIyYwz8uZvF4aex1+wnhnt1X60g7mAku41tCr+jb5UiwRVY0ne8ncue7+m4nluNd X-Received: by 2002:a17:906:1d52:: with SMTP id o18mr24843203ejh.399.1591726619296; Tue, 09 Jun 2020 11:16:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591726619; cv=none; d=google.com; s=arc-20160816; b=CQ7GQcD07S3LIbkzQCmEbEYd7f55l3e5qQtd0lIiDSKFvCAlZVSww1OYqdbdY16vNj Km4XiZ1EpfmcPyKP/dNWJFw+YDLcQV8s4yOLBjB82Ouuvh0Axo4Uqbkzsos+Z+y80R8c oUkIGZlfIlxJeXaf8MUbHWuS7BAxmUB4JdAzPvkIzPVMo+O/pzGb2VQNY+ZVuQkhmIku hYu56kCrHBqEEbIOBiRW2hwJTYnMZcY67NvY7+PsFcVZMDXdw/PIZgNzu3VmJQX5980T FeYoX+Dox26A422iBfb29+vR4aYFIYKZRKCOgJc0PCeLCl6RSmxggLcPOimvsF7wNaWK LEcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=OFRZE0tUOdYS7pVpn//RIzGzQQ9fouoz+8PLrhOohPI=; b=tmhbbTQIlLZPhfmFJRld8f/nkHeYUXdom4bzCPk2VOODcYTvaf+r8vrA7ggMAkVlLz sbHxz8ZvgaTqu8unQYJZIiRRY16Uk8AuaUGbQpcpT5Lja63Rd2grZa2D8qPXp6R08wjV 8phCY+NhyTweS+mlGXamPEslHTdzNfRjGT6owdfsrAOuwum31tss2xnICjMdIK3RMpJv ebpqRpqxARBHz9foh5wv6hGeS6kKtYh7AhMiC5j9aBDDji5i4jJUpe/s9hwnzuiDvmWb GqQND6lR05VOwdudwIqVJ5Ok4pdxxu4vpRZ939Ur+lzMdBZh5sX/ZclcmoXEFtGK4eDQ U3WA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=h16I3SPN; 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 p20si11294712ejg.263.2020.06.09.11.16.04; Tue, 09 Jun 2020 11:16:59 -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=pass header.i=@kernel.org header.s=default header.b=h16I3SPN; 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 S2388727AbgFISMq (ORCPT + 99 others); Tue, 9 Jun 2020 14:12:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:40048 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731159AbgFIRvS (ORCPT ); Tue, 9 Jun 2020 13:51:18 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 31CF5207F9; Tue, 9 Jun 2020 17:51:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591725077; bh=7H0o9iPkpfeRrO+kK8fHciPXul+ErU2mXc1tBvSlrxs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=h16I3SPN2jsOyARTHUArVV3/CRItM5JQo7T0eGL0rEbfOtA1V+z7359SToqpXMGwL PiZNRLZUizbnPTrq6zkTNPtcLrT4ooaWVTvVW/h6yTD+EhQ182CWAl2GUWY6OlGVj7 XMnXx8I0m1pc7V3keF5jJOJfO1rZfFk5xpWeGbU4= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jiri Slaby , Raghavendra Subject: [PATCH 4.19 15/25] tty: hvc_console, fix crashes on parallel open/close Date: Tue, 9 Jun 2020 19:45:05 +0200 Message-Id: <20200609174050.357586554@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200609174048.576094775@linuxfoundation.org> References: <20200609174048.576094775@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jiri Slaby commit 24eb2377f977fe06d84fca558f891f95bc28a449 upstream. hvc_open sets tty->driver_data to NULL when open fails at some point. Typically, the failure happens in hp->ops->notifier_add(). If there is a racing process which tries to open such mangled tty, which was not closed yet, the process will crash in hvc_open as tty->driver_data is NULL. All this happens because close wants to know whether open failed or not. But ->open should not NULL this and other tty fields for ->close to be happy. ->open should call tty_port_set_initialized(true) and close should check by tty_port_initialized() instead. So do this properly in this driver. So this patch removes these from ->open: * tty_port_tty_set(&hp->port, NULL). This happens on last close. * tty->driver_data = NULL. Dtto. * tty_port_put(&hp->port). This happens in shutdown and until now, this must have been causing a reference underflow, if I am not missing something. Signed-off-by: Jiri Slaby Cc: stable Reported-and-tested-by: Raghavendra Link: https://lore.kernel.org/r/20200526145632.13879-1-jslaby@suse.cz Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_console.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -371,15 +371,14 @@ static int hvc_open(struct tty_struct *t * tty fields and return the kref reference. */ if (rc) { - tty_port_tty_set(&hp->port, NULL); - tty->driver_data = NULL; - tty_port_put(&hp->port); printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); - } else + } else { /* We are ready... raise DTR/RTS */ if (C_BAUD(tty)) if (hp->ops->dtr_rts) hp->ops->dtr_rts(hp, 1); + tty_port_set_initialized(&hp->port, true); + } /* Force wakeup of the polling thread */ hvc_kick(); @@ -389,22 +388,12 @@ static int hvc_open(struct tty_struct *t static void hvc_close(struct tty_struct *tty, struct file * filp) { - struct hvc_struct *hp; + struct hvc_struct *hp = tty->driver_data; unsigned long flags; if (tty_hung_up_p(filp)) return; - /* - * No driver_data means that this close was issued after a failed - * hvc_open by the tty layer's release_dev() function and we can just - * exit cleanly because the kref reference wasn't made. - */ - if (!tty->driver_data) - return; - - hp = tty->driver_data; - spin_lock_irqsave(&hp->port.lock, flags); if (--hp->port.count == 0) { @@ -412,6 +401,9 @@ static void hvc_close(struct tty_struct /* We are done with the tty pointer now. */ tty_port_tty_set(&hp->port, NULL); + if (!tty_port_initialized(&hp->port)) + return; + if (C_HUPCL(tty)) if (hp->ops->dtr_rts) hp->ops->dtr_rts(hp, 0); @@ -428,6 +420,7 @@ static void hvc_close(struct tty_struct * waking periodically to check chars_in_buffer(). */ tty_wait_until_sent(tty, HVC_CLOSE_WAIT); + tty_port_set_initialized(&hp->port, false); } else { if (hp->port.count < 0) printk(KERN_ERR "hvc_close %X: oops, count is %d\n",