Skip to content

Commit

Permalink
bridge: Prevent possible race condition in br_fdb_change_mac_address
Browse files Browse the repository at this point in the history
br_fdb_change_mac_address() calls fdb_insert()/fdb_delete() without
br->hash_lock.

These hash list updates are racy with br_fdb_update()/br_fdb_cleanup().

Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
Acked-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Toshiaki Makita authored and David S. Miller committed Feb 10, 2014
1 parent 424bb9c commit ac4c886
Showing 1 changed file with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion net/bridge/br_fdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
struct net_port_vlans *pv;
u16 vid = 0;

spin_lock_bh(&br->hash_lock);

/* If old entry was unassociated with any port, then delete it. */
f = __br_fdb_get(br, br->dev->dev_addr, 0);
if (f && f->is_local && !f->dst)
Expand All @@ -204,14 +206,16 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
*/
pv = br_get_vlan_info(br);
if (!pv)
return;
goto out;

for_each_set_bit_from(vid, pv->vlan_bitmap, VLAN_N_VID) {
f = __br_fdb_get(br, br->dev->dev_addr, vid);
if (f && f->is_local && !f->dst)
fdb_delete_local(br, NULL, f);
fdb_insert(br, NULL, newaddr, vid);
}
out:
spin_unlock_bh(&br->hash_lock);
}

void br_fdb_cleanup(unsigned long _data)
Expand Down

0 comments on commit ac4c886

Please sign in to comment.