Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp2662499imj; Mon, 11 Feb 2019 06:39:27 -0800 (PST) X-Google-Smtp-Source: AHgI3IbbkjNj+Tv9+auLUurWTix5lbK7lPGwCzbwfdC5Kg3zlwGx9WafZ1280JjQ8SPvJgluoGfS X-Received: by 2002:a65:6219:: with SMTP id d25mr19120961pgv.18.1549895967529; Mon, 11 Feb 2019 06:39:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549895967; cv=none; d=google.com; s=arc-20160816; b=X/cjp1BaALSIDjAkD7Niw3lzD8plpGlrhPDylUEB+bNdp/uUhupaA+MrYbYpnEu6Y7 +rrG+PzBWLCbuqNjKwP8jG0hklDCNKkL1SrL8GWrcb5ZkQRlbCJCo+FFOYie5dP+hoAn Z4eV3zqS9iWmTXz01XdaYQmlh8t6HLjYmPjSuXreu3lZO2SR6Kda9Pj1hiHfL3YgDYks 2dR6/MjRZAqs1wSsEPXvaE/wudo1ib3ZnX79/o0TcIvn2JnuFX/+02HpJH9T4MaaKg/D OpvbHsx8hh1jSLoDzC5eq+jxxfj5wFklYvk/DVMKA4kcZkdd/DOYyOO27Shda9RRTXHh mSgQ== 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=HaMfnyULQdPco4aQayNElk3i0zFOlNSCGaIw8VesOgc=; b=D+MivAHLZBJsz+dyEVTVvbcYJE8+bxOWL5uQgaH7d4+me7/08cIEKY6CSpQHo4n10n n64Kq3EdfQhbICCAlwdhTIM9Qk8cf5fWGIs8T9TRgg6u/Ri7IRFyYZ+geZL8tiCFF7U+ jntYhStASOdE23wimDZ6fNPMLNatUc7Jsp02zxvwykZIhLkjOD6TXNDWJ9vn3mAjyfqN f6/qCcfXRstay2NqqFcnkXwUpmnt6FZWJ6h8RJ3ohbPlgYDjaDvx5ZgZnOvT9kfch8Fr wuJPJxRJ+e/e1AKLYzPBIN6eLKDZ74HCsDQqBG18w37GX/vF2F4Msn9GHr1Qzte3e4A8 EndA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=nxz1r5at; 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 v11si10619412plo.377.2019.02.11.06.39.11; Mon, 11 Feb 2019 06:39:27 -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; dkim=pass header.i=@kernel.org header.s=default header.b=nxz1r5at; 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 S1731652AbfBKOiT (ORCPT + 99 others); Mon, 11 Feb 2019 09:38:19 -0500 Received: from mail.kernel.org ([198.145.29.99]:48018 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731641AbfBKOiT (ORCPT ); Mon, 11 Feb 2019 09:38:19 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.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 2D60B20844; Mon, 11 Feb 2019 14:38:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1549895897; bh=1ilPmTGcTLD9FvivOlIe+ycuAiaRCVd7TJ7Ozhw5+EQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nxz1r5atRpFZ4Ypa0WfAleiuUoaqgYdG5lkqjoRxeUi0IcviCFTU/qo12KfFRJ0/Y 5TcMrLCy7LUwCiXz5RkzwpIbu652+bCpWUVjcfqdvXPIQnIzytb7IrF+U4LIlNyl1z BYxQlpcW7QvnfEarrSAIWfVa5fTc6lyDcJo+ZYbE= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Li RongQing , Wang Li , Zhang Yu Subject: [PATCH 4.20 348/352] serial: fix race between flush_to_ldisc and tty_open Date: Mon, 11 Feb 2019 15:19:35 +0100 Message-Id: <20190211141909.329117127@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190211141846.543045703@linuxfoundation.org> References: <20190211141846.543045703@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore 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 4.20-stable review patch. If anyone has any objections, please let me know. ------------------ From: Greg Kroah-Hartman commit fedb5760648a291e949f2380d383b5b2d2749b5e upstream. There still is a race window after the commit b027e2298bd588 ("tty: fix data race between tty_init_dev and flush of buf"), and we encountered this crash issue if receive_buf call comes before tty initialization completes in tty_open and tty->driver_data may be NULL. CPU0 CPU1 ---- ---- tty_open tty_init_dev tty_ldisc_unlock schedule flush_to_ldisc receive_buf tty_port_default_receive_buf tty_ldisc_receive_buf n_tty_receive_buf_common __receive_buf uart_flush_chars uart_start /*tty->driver_data is NULL*/ tty->ops->open /*init tty->driver_data*/ it can be fixed by extending ldisc semaphore lock in tty_init_dev to driver_data initialized completely after tty->ops->open(), but this will lead to get lock on one function and unlock in some other function, and hard to maintain, so fix this race only by checking tty->driver_data when receiving, and return if tty->driver_data is NULL, and n_tty_receive_buf_common maybe calls uart_unthrottle, so add the same check. Because the tty layer knows nothing about the driver associated with the device, the tty layer can not do anything here, it is up to the tty driver itself to check for this type of race. Fix up the serial driver to correctly check to see if it is finished binding with the device when being called, and if not, abort the tty calls. [Description and problem report and testing from Li RongQing, I rewrote the patch to be in the serial layer, not in the tty core - gregkh] Reported-by: Li RongQing Tested-by: Li RongQing Signed-off-by: Wang Li Signed-off-by: Zhang Yu Signed-off-by: Li RongQing Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 6 ++++++ 1 file changed, 6 insertions(+) --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -130,6 +130,9 @@ static void uart_start(struct tty_struct struct uart_port *port; unsigned long flags; + if (!state) + return; + port = uart_port_lock(state, flags); __uart_start(tty); uart_port_unlock(port, flags); @@ -727,6 +730,9 @@ static void uart_unthrottle(struct tty_s upstat_t mask = UPSTAT_SYNC_FIFO; struct uart_port *port; + if (!state) + return; + port = uart_port_ref(state); if (!port) return;