Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bridge: fix bridge netlink RCU usage

When the STP timer fires, it can call br_ifinfo_notify(),
which in turn ends up in the new br_get_link_af_size().
This function is annotated to be using RTNL locking, which
clearly isn't the case here, and thus lockdep warns:

===============================
[ INFO: suspicious RCU usage. ]
3.19.0+ #569 Not tainted
-------------------------------
net/bridge/br_private.h:204 suspicious rcu_dereference_protected() usage!

Fix this by doing RCU locking here.

Fixes: b7853d73e39b ("bridge: add vlan info to bridge setlink and dellink notification messages")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Johannes Berg and committed by
David S. Miller
2f56f6be 71a83a6d

+8 -6
+8 -6
net/bridge/br_netlink.c
··· 81 81 struct net_port_vlans *pv; 82 82 int num_vlan_infos; 83 83 84 + rcu_read_lock(); 84 85 if (br_port_exists(dev)) 85 - pv = nbp_get_vlan_info(br_port_get_rtnl(dev)); 86 + pv = nbp_get_vlan_info(br_port_get_rcu(dev)); 86 87 else if (dev->priv_flags & IFF_EBRIDGE) 87 88 pv = br_get_vlan_info((struct net_bridge *)netdev_priv(dev)); 88 89 else 89 - return 0; 90 + pv = NULL; 91 + if (pv) 92 + num_vlan_infos = br_get_num_vlan_infos(pv, filter_mask); 93 + else 94 + num_vlan_infos = 0; 95 + rcu_read_unlock(); 90 96 91 - if (!pv) 92 - return 0; 93 - 94 - num_vlan_infos = br_get_num_vlan_infos(pv, filter_mask); 95 97 if (!num_vlan_infos) 96 98 return 0; 97 99