Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp5336749ybl; Tue, 14 Jan 2020 07:19:54 -0800 (PST) X-Google-Smtp-Source: APXvYqz+AFfYngK5t3YH+lNH7sJVNTmyweZxElXmQsj/nSt/wEegoBsdY+BQ1IiXkEOOYp7F42VK X-Received: by 2002:a9d:7b4a:: with SMTP id f10mr18213368oto.4.1579015194514; Tue, 14 Jan 2020 07:19:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579015194; cv=none; d=google.com; s=arc-20160816; b=qXToy6+wTw8KlNTGd25JbiZvFXtDrztH4ZyzFH2xJKu+AfVtmD5KtkCJ7QGf2wZyJ6 oW1px19J0WvSVN+wChPjYWdac0n5hKexOoh+Vi3kqo2vpW8XTBVe0Q3NDhtJLnWvjYco 4lpbOzrFb07tJA5ZoKuC/rLCci/M/8nqiHfN8R2GJLOCwmIm9ieAb51aTn/1XpS5/IFv 8RDIlV/VEypeA8GqnH+QXYRMfhrWeg9HBRHxUKxF9aPfAPxsP1ygVCb5iSIoFrxWETPK wmaRUlvh3+kbOKmhDkVqzKwbr6cG8OVja7NdDebqZ9HZZifCFPj9TpbY+3FJocIxIE+5 CKlw== 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 :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=NccOTQjRE3K/mry3ktyfcVSqMgiS7x0ndgHbwmuP8TQ=; b=AJ41cTse2C6PWKaXJ8AAmaWdB/B94sM5WN13q6JHYZYKOT4WsMXSY8GPy6YB0RcG93 cv0dXEIx0eVYlStVax6TgD5X30Ot1BGzGJvL9VStTn3lcnQPbQRORBvyY/V6v3B0Q/GD Pj/UtRpKk7Y5saf0v/Bjev2eFlr0835Nrj+za76HU94zkIlpiDlbXJQMkD3+OYYz2GO3 7rbBR9Fv5yAriHZePFW4zUop+FD1fLvVWzHbuV39/HtJMpg3co7BIA1p6D93HsWcZAUs qoWrSTDygLrcPLmHiCDm4vb9CdQW73ApB3vaT8o9kqJui3HnK5v+b/hmOWDqFIZpWrbU 1+qQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=eZt7jWyj; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q7si7861970otn.108.2020.01.14.07.19.43; Tue, 14 Jan 2020 07:19:54 -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=@gmail.com header.s=20161025 header.b=eZt7jWyj; 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; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729112AbgANPRz (ORCPT + 99 others); Tue, 14 Jan 2020 10:17:55 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:38478 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726335AbgANPRy (ORCPT ); Tue, 14 Jan 2020 10:17:54 -0500 Received: by mail-pf1-f194.google.com with SMTP id x185so6734314pfc.5; Tue, 14 Jan 2020 07:17:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language:content-transfer-encoding; bh=NccOTQjRE3K/mry3ktyfcVSqMgiS7x0ndgHbwmuP8TQ=; b=eZt7jWyj1lFcAl+nxOMeOUkRlU/C5B9gtr1fYUIkxqtPV7ZLoHlFBT9L+nnBkuVvsI 76KXt4W1Sc/eX0hJHYnfXtkmSrjtCzlZ4knqTozpPeGS4awMa/uhW5RKe5F5IK2KxtcC hSzOwtndvb3vc2n6un8ZoX7X3QF2T/PHZVi/kZFTqibdl06MqwPVw9EtcTZ7Xbs72esb OBxlvh7+wXJQbjJw+voB2QhTM2w3dpqxOA2xLLooA4mWpZxvX4FsZPnXWCM99GvyABb/ hJDBBKujbLMqDpB5XfxABB6VDerelAx8BJIceJDqMh0DTximUuNaWkMvTKfp2kbMGLGf M9sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=NccOTQjRE3K/mry3ktyfcVSqMgiS7x0ndgHbwmuP8TQ=; b=i47GzduhUsvnFM57j1NA7YQ8xQhWXKR5r5r9QlXL0uTfTv2PZ4u7wFQP8Qif3c/wkM PWjf5decpgSCE6sudoJAoj0E+lEjyEY61lqwj1TALuDdIf87b9pUnuI3hIYlcc8kvYFc 3ilQa8UGVnbYS9WlOUaCn6iw5PgKLknLFpomr8J3FGoOe8UfpX95PA2RpuUUqMmDmuPc XeiUjk7Nx2fDaTQ06/R+Vo3kJlbWhk5/OTP54P1a5np9VbsfCfTrS2QhliVSjUagl51a k3T1ZaRCRrDuXMqXSmfYypCyE/K7lkn1sKRkygTxaI+XCGFKPTTLSksVzc1Rbis6di6b viPg== X-Gm-Message-State: APjAAAU4I3C1rklI4BT/MTdYdBaknLnfWdEEW/HPphC9GMVAlBDpmDA/ CWoiYMtWElIF13Tjm+FXXPs= X-Received: by 2002:a63:b005:: with SMTP id h5mr26671855pgf.67.1579015073738; Tue, 14 Jan 2020 07:17:53 -0800 (PST) Received: from [192.168.86.235] (c-73-241-150-58.hsd1.ca.comcast.net. [73.241.150.58]) by smtp.gmail.com with ESMTPSA id s131sm20232099pfs.135.2020.01.14.07.17.52 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 14 Jan 2020 07:17:52 -0800 (PST) Subject: Re: [PATCH] can, slip: Protect tty->disc_data access with RCU To: Richard Palethorpe , linux-can@vger.kernel.org Cc: syzbot+017e491ae13c0068598a@syzkaller.appspotmail.com, Wolfgang Grandegger , Marc Kleine-Budde , "David S. Miller" , Tyler Hall , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, syzkaller@googlegroups.com References: <0000000000002b81b70590a83ad7@google.com> <20200114143244.20739-1-rpalethorpe@suse.com> From: Eric Dumazet Message-ID: <19d5e4c6-72f4-631f-2ccd-b5df660a5ef6@gmail.com> Date: Tue, 14 Jan 2020 07:17:51 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.2.2 MIME-Version: 1.0 In-Reply-To: <20200114143244.20739-1-rpalethorpe@suse.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 1/14/20 6:32 AM, Richard Palethorpe wrote: > write_wakeup can happen in parallel with close where tty->disc_data is set > to NULL. So we a) need to check if tty->disc_data is NULL and b) ensure it > is an atomic operation. Otherwise accessing tty->disc_data could result in > a NULL pointer deref or access to some random location. > > This problem was found by Syzkaller on slcan, but the same issue appears to > exist in slip where slcan was copied from. > > 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: netdev@vger.kernel.org > Cc: linux-kernel@vger.kernel.org > Cc: syzkaller@googlegroups.com > --- > > Note, that mabye RCU should also applied to receive_buf as that also happens > in interrupt context. So if the pointer assignment is split by the compiler > then sl may point somewhere unexpected? > > drivers/net/can/slcan.c | 11 +++++++++-- > drivers/net/slip/slip.c | 11 +++++++++-- > 2 files changed, 18 insertions(+), 4 deletions(-) > > diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c > index 2e57122f02fb..ee029aae69d4 100644 > --- a/drivers/net/can/slcan.c > +++ b/drivers/net/can/slcan.c > @@ -344,7 +344,14 @@ static void slcan_transmit(struct work_struct *work) > */ > 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); > + rcu_read_unlock(); This rcu_read_lock()/rcu_read_unlock() pair is not protecting anything. Right after rcu_read_unlock(), sl validity can not be guaranteed. > + > + if (!sl) > + return; > > schedule_work(&sl->tx_work); > } > @@ -644,7 +651,7 @@ static void slcan_close(struct tty_struct *tty) > 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); Where is the rcu grace period before freeing enforced ? > > diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c > index 2a91c192659f..dfed9f0b8646 100644 > --- a/drivers/net/slip/slip.c > +++ b/drivers/net/slip/slip.c > @@ -452,7 +452,14 @@ static void slip_transmit(struct work_struct *work) > */ > 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); > + rcu_read_unlock(); Same here. > + > + if (!sl) > + return; > > schedule_work(&sl->tx_work); > } > @@ -882,7 +889,7 @@ static void slip_close(struct tty_struct *tty) > 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); > >