Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp1085857pxk; Fri, 25 Sep 2020 06:01:15 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwCdFu3TLWkqS+SxMf4qcLnZ3XrOBNHMpXwd7KcszpA0aOttfD9jt1EBBTyXdIS74Uy8hIG X-Received: by 2002:a05:6402:1818:: with SMTP id g24mr1160421edy.332.1601038875378; Fri, 25 Sep 2020 06:01:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601038875; cv=none; d=google.com; s=arc-20160816; b=hYcoNmDVG+Wf+2iEBHnInobtK/CEpqXLLTO9tenCgr4gflvPkVAr5nKFjLFjPElKh7 xF3iwxPXxqy3Cr/w6D/Z1ptnFIgfM3xQkvc8xApJMpcYzTrqLpe5INiaCSG2EY7yAcgr SF48i1a7pysaG3qbHLFajVT9D60yMt4qmavR3UighHdmpqrivgQwhdLZPtmEo94Wi6bQ 31dpmuulKFKLDXB0We31Uc53bip21ZbT2f2df5zPegL9Y7MuaMifvBIiVTDL0KJR+CcD 1UI4Mdjz9mVvEo3pBC4uUhaEPh2fpRqxDb2Efo//Ym5MeOyEtMHlkx35XflocjspwBXj bVmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=VHrsrXiAgWyPq2Pf0m2SQiR6qrkHBlehyHpNBkH4Zg4=; b=k1wENVk1M/ky2ueEwg6GZPgodsS8h+R17v+b64VcKMf6Z9PQ/0oF9eGBVw9uyiKlts Y5lNtaEFyY+8g0SFx0+BC64+hU2EwBRK7jGrX9ntOf0XD6r7Bzz4xODr3KT2VQ7IWBk8 8vjHK5l+Bb+HvglqSomojo4Hk71430lv6b9QGcf+MTUJ+ZOhKumUn4c3Fdl1naTnC3yV hF4bFE+ax5lGEsk+v5kC57rGi7HRhEtMv1Ikq/zeZDzSiKiFzAm/CMoPzX2UjqVcSrq8 FjCTmE5pm3x8lL6YkLM392LPZGDlcIm9/wTmicAtxC8MaBWYn5G6whJwQSb4MUrjCinF rOyw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=Tc8bDKdz; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b19si1791558edw.155.2020.09.25.06.00.51; Fri, 25 Sep 2020 06:01:15 -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=Tc8bDKdz; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728796AbgIYM4t (ORCPT + 99 others); Fri, 25 Sep 2020 08:56:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:55964 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729210AbgIYMve (ORCPT ); Fri, 25 Sep 2020 08:51:34 -0400 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (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 966B621741; Fri, 25 Sep 2020 12:51:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1601038294; bh=2lpjlTn420XdbgFw622omkZ/LENmHhU/R9F5caD0xRk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Tc8bDKdzCimllLf+D3dlxcZ9vwLnK4Ijg+4izC88Nlzqhpp74xasjUYf73bbCVznA MrteSTPsEB1BjUxzWSxvFOxZiY98xhyaEdYgkYWCmRbwbINseqhZGNmqU1wCrjox5L l3wbq4wlFm7QaDswz1nOPbNKDRtmmnQlb1Y+5bss= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Vladimir Oltean , "David S. Miller" Subject: [PATCH 5.4 17/43] net: bridge: br_vlan_get_pvid_rcu() should dereference the VLAN group under RCU Date: Fri, 25 Sep 2020 14:48:29 +0200 Message-Id: <20200925124726.178619091@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200925124723.575329814@linuxfoundation.org> References: <20200925124723.575329814@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vladimir Oltean [ Upstream commit 99f62a746066fa436aa15d4606a538569540db08 ] When calling the RCU brother of br_vlan_get_pvid(), lockdep warns: ============================= WARNING: suspicious RCU usage 5.9.0-rc3-01631-g13c17acb8e38-dirty #814 Not tainted ----------------------------- net/bridge/br_private.h:1054 suspicious rcu_dereference_protected() usage! Call trace: lockdep_rcu_suspicious+0xd4/0xf8 __br_vlan_get_pvid+0xc0/0x100 br_vlan_get_pvid_rcu+0x78/0x108 The warning is because br_vlan_get_pvid_rcu() calls nbp_vlan_group() which calls rtnl_dereference() instead of rcu_dereference(). In turn, rtnl_dereference() calls rcu_dereference_protected() which assumes operation under an RCU write-side critical section, which obviously is not the case here. So, when the incorrect primitive is used to access the RCU-protected VLAN group pointer, READ_ONCE() is not used, which may cause various unexpected problems. I'm sad to say that br_vlan_get_pvid() and br_vlan_get_pvid_rcu() cannot share the same implementation. So fix the bug by splitting the 2 functions, and making br_vlan_get_pvid_rcu() retrieve the VLAN groups under proper locking annotations. Fixes: 7582f5b70f9a ("bridge: add br_vlan_get_pvid_rcu()") Signed-off-by: Vladimir Oltean Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/bridge/br_vlan.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -1229,11 +1229,13 @@ void br_vlan_get_stats(const struct net_ } } -static int __br_vlan_get_pvid(const struct net_device *dev, - struct net_bridge_port *p, u16 *p_pvid) +int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid) { struct net_bridge_vlan_group *vg; + struct net_bridge_port *p; + ASSERT_RTNL(); + p = br_port_get_check_rtnl(dev); if (p) vg = nbp_vlan_group(p); else if (netif_is_bridge_master(dev)) @@ -1244,18 +1246,23 @@ static int __br_vlan_get_pvid(const stru *p_pvid = br_get_pvid(vg); return 0; } - -int br_vlan_get_pvid(const struct net_device *dev, u16 *p_pvid) -{ - ASSERT_RTNL(); - - return __br_vlan_get_pvid(dev, br_port_get_check_rtnl(dev), p_pvid); -} EXPORT_SYMBOL_GPL(br_vlan_get_pvid); int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid) { - return __br_vlan_get_pvid(dev, br_port_get_check_rcu(dev), p_pvid); + struct net_bridge_vlan_group *vg; + struct net_bridge_port *p; + + p = br_port_get_check_rcu(dev); + if (p) + vg = nbp_vlan_group_rcu(p); + else if (netif_is_bridge_master(dev)) + vg = br_vlan_group_rcu(netdev_priv(dev)); + else + return -EINVAL; + + *p_pvid = br_get_pvid(vg); + return 0; } EXPORT_SYMBOL_GPL(br_vlan_get_pvid_rcu);