Skip to contentSkip to conversation

Patch "bridge: fix br_stp_set_bridge_priority race conditions" has been added to the 4.0-stable tree

PATCH [email protected] 1 participant 1 message Jul 4, 2015

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

bridge: fix br_stp_set_bridge_priority race conditions

to the 4.0-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
bridge-fix-br_stp_set_bridge_priority-race-conditions.patch
and it can be found in the queue-4.0 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From foo@baz Fri Jul 3 19:59:52 PDT 2015

From: Nikolay Aleksandrov <[email protected]>
Date: Mon, 15 Jun 2015 20:28:51 +0300
Subject: bridge: fix br_stp_set_bridge_priority race conditions

From: Nikolay Aleksandrov <[email protected]>

[ Upstream commit 2dab80a8b486f02222a69daca6859519e05781d9 ]

After the ->set() spinlocks were removed br_stp_set_bridge_priority was left running without any protection when used via sysfs. It can race with port add/del and could result in use-after-free cases and corrupted lists. Tested by running port add/del in a loop with stp enabled while setting priority in a loop, crashes are easily reproducible.
The spinlocks around sysfs ->set() were removed in commit:
14f98f258f19 ("bridge: range check STP parameters")
There's also a race condition in the netlink priority support that is fixed by this change, but it was introduced recently and the fixes tag covers it, just in case it's needed the commit is:
af615762e972 ("bridge: add ageing_time, stp_state, priority over netlink")

Fixes 14f98f258f19 ("bridge: range check STP parameters")
---
 net/bridge/br_ioctl.c  |    2 --
 net/bridge/br_stp_if.c |    4 +++-
 2 files changed, 3 insertions(+), 3 deletions(-)
net/bridge/br_ioctl.c +0 -2
@@ -247,9 +247,7 @@ static int old_dev_ioctl(struct net_devi
 		if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN))
 			return -EPERM;
 
-		spin_lock_bh(&br->lock);
 		br_stp_set_bridge_priority(br, args[1]);
-		spin_unlock_bh(&br->lock);
 		return 0;
 
 	case BRCTL_SET_PORT_PRIORITY:
net/bridge/br_stp_if.c +3 -1
@@ -243,12 +243,13 @@ bool br_stp_recalculate_bridge_id(struct
 	return true;
 }
 
-/* called under bridge lock */
+/* Acquires and releases bridge lock */
 void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio)
 {
 	struct net_bridge_port *p;
 	int wasroot;
 
+	spin_lock_bh(&br->lock);
 	wasroot = br_is_root_bridge(br);
 
 	list_for_each_entry(p, &br->port_list, list) {
@@ -266,6 +267,7 @@ void br_stp_set_bridge_priority(struct n
 	br_port_state_selection(br);
 	if (br_is_root_bridge(br) && !wasroot)
 		br_become_root_bridge(br);
+	spin_unlock_bh(&br->lock);
 }
 
 /* called under bridge lock */

Patches currently in stable-queue which might be from [email protected] are

queue-4.0/bridge-fix-br_stp_set_bridge_priority-race-conditions.patch queue-4.0/bridge-fix-multicast-router-rlist-endless-loop.patch