Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp456191ybl; Tue, 28 Jan 2020 06:15:51 -0800 (PST) X-Google-Smtp-Source: APXvYqz3Z2DjZ6/evFP78Pvr0+I/7+6owgd50Sg6EX9+082w7SJYiVZogkgtYAXyc87nrtK0nxr5 X-Received: by 2002:aca:f445:: with SMTP id s66mr2816431oih.95.1580220951612; Tue, 28 Jan 2020 06:15:51 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580220951; cv=none; d=google.com; s=arc-20160816; b=QHuSgRl0gXoYvy2L67D+xCfEhda33xa/ydkuyU9+3cw4Yuq4xe/9XXRgcAyUsKbUzn g/BiN38Kh4XZloBWTXdZVjtwgxrotY4KIFpKOmjRZkU2LL089BTz61XQdUGPQ0QrfCoA fvWLtRp82VrYcaR89BF/mYbodxbNpzxmVe4e8v9HqaXn+D4tvBVn/LGbAx9YpC809fcD e88Pgj1w5o32bOSpRstHp9mXRJgUXQkU4rIqeoepb0KlqovmAUeL1BC5zxNj5pW7q6HD HoOB+vDxn/NHn8gFCkEN8QI28mctlYETryBZoWyv5LPkGPhQLkXnj0nOcvV7McT/Oz/7 EMQQ== 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=Q3vYk1Nj/LOUcSBKBpdFewZluf4nTOlQ9KNg2SEJHSg=; b=zyTu25b20UidfiB3N9sSwl2I5VKd+pNI3NUQBjFUI1I4dNVpYlXjr48D6fqpbT/KKu VuPTSpyb0KaodjAFJHMve7O7biq8ICB2g2sa9YOkqpF7ZleldS7ssnmmu/vWrQCvZ92m UwXwsDi6iAkOdHg2y9WZxLRlj6NH6Prmj4IMJ4gTRuQFFVO2AevYtT3jmrlqSFB0RGBY PKtq1NiWHbfmASR68cHUBcdGSRhOG0+mpxJJjREUnVqR0kVKws525649Jnh+vEUixCvR a61JkbCZ1TOKZFu1PHwHU9TbIjvQ3WOTZFMQEx+/TrQyFdI9sjVLnBCYgvSEKzOoecQ7 1B3g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="AjhnUc/7"; 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 d23si5039992oij.270.2020.01.28.06.15.39; Tue, 28 Jan 2020 06:15:51 -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="AjhnUc/7"; 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 S1729524AbgA1ONq (ORCPT + 99 others); Tue, 28 Jan 2020 09:13:46 -0500 Received: from mail.kernel.org ([198.145.29.99]:35318 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729353AbgA1ONj (ORCPT ); Tue, 28 Jan 2020 09:13:39 -0500 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 E41F524688; Tue, 28 Jan 2020 14:13:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1580220818; bh=N53L2593G9AItP5Hfi5f6AE/8lIDgtBvs63EpGa8FJM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AjhnUc/7pBLAljg5qn4P3Cq9GYEwVJfE2C5Zv0fs2RZ9Ad6CzEb4+1Zhnf+5TtXgw +9hhFyRyz+JTmyEHsJg1tpuGAlDi190jkMET6fXmW8M1lYczv37PYv4nJ2MUxJO/5l pTM57e7qA3nSs7xq0TgTCU6lPbeUgQdXdxdrutE8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+017e491ae13c0068598a@syzkaller.appspotmail.com, Richard Palethorpe , Wolfgang Grandegger , Marc Kleine-Budde , "David S. Miller" , Tyler Hall , linux-can@vger.kernel.org, netdev@vger.kernel.org, syzkaller@googlegroups.com Subject: [PATCH 4.4 160/183] can, slip: Protect tty->disc_data in write_wakeup and close with RCU Date: Tue, 28 Jan 2020 15:06:19 +0100 Message-Id: <20200128135845.698951055@linuxfoundation.org> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200128135829.486060649@linuxfoundation.org> References: <20200128135829.486060649@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: Richard Palethorpe [ Upstream commit 0ace17d56824165c7f4c68785d6b58971db954dd ] write_wakeup can happen in parallel with close/hangup where tty->disc_data is set to NULL and the netdevice is freed thus also freeing disc_data. write_wakeup accesses disc_data so we must prevent close from freeing the netdev while write_wakeup has a non-NULL view of tty->disc_data. We also need to make sure that accesses to disc_data are atomic. Which can all be done with RCU. This problem was found by Syzkaller on SLCAN, but the same issue is reproducible with the SLIP line discipline using an LTP test based on the Syzkaller reproducer. A fix which didn't use RCU was posted by Hillf Danton. Fixes: 661f7fda21b1 ("slip: Fix deadlock in write_wakeup") Fixes: a8e83b17536a ("slcan: Port write_wakeup deadlock fix from slip") Reported-by: syzbot+017e491ae13c0068598a@syzkaller.appspotmail.com Signed-off-by: Richard Palethorpe Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: "David S. Miller" Cc: Tyler Hall Cc: linux-can@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: syzkaller@googlegroups.com Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/net/can/slcan.c | 12 ++++++++++-- drivers/net/slip/slip.c | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -344,9 +344,16 @@ static void slcan_transmit(struct work_s */ static void slcan_write_wakeup(struct tty_struct *tty) { - struct slcan *sl = tty->disc_data; + struct slcan *sl; + + rcu_read_lock(); + sl = rcu_dereference(tty->disc_data); + if (!sl) + goto out; schedule_work(&sl->tx_work); +out: + rcu_read_unlock(); } /* Send a can_frame to a TTY queue. */ @@ -640,10 +647,11 @@ static void slcan_close(struct tty_struc return; spin_lock_bh(&sl->lock); - tty->disc_data = NULL; + rcu_assign_pointer(tty->disc_data, NULL); sl->tty = NULL; spin_unlock_bh(&sl->lock); + synchronize_rcu(); flush_work(&sl->tx_work); /* Flush network side */ --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -452,9 +452,16 @@ static void slip_transmit(struct work_st */ static void slip_write_wakeup(struct tty_struct *tty) { - struct slip *sl = tty->disc_data; + struct slip *sl; + + rcu_read_lock(); + sl = rcu_dereference(tty->disc_data); + if (!sl) + goto out; schedule_work(&sl->tx_work); +out: + rcu_read_unlock(); } static void sl_tx_timeout(struct net_device *dev) @@ -887,10 +894,11 @@ static void slip_close(struct tty_struct return; spin_lock_bh(&sl->lock); - tty->disc_data = NULL; + rcu_assign_pointer(tty->disc_data, NULL); sl->tty = NULL; spin_unlock_bh(&sl->lock); + synchronize_rcu(); flush_work(&sl->tx_work); /* VSV = very important to remove timers */