Patchwork [3.5.y.z,extended,stable] Patch "bonding: fix bonding_masters race condition in bond unloading" has been added to staging queue

login
register
mail settings
Submitter Luis Henriques
Date May 1, 2013, 11:34 p.m.
Message ID <1367451282-20070-1-git-send-email-luis.henriques@canonical.com>
Download mbox | patch
Permalink /patch/240863/
State New
Headers show

Comments

Luis Henriques - May 1, 2013, 11:34 p.m.
This is a note to let you know that I have just added a patch titled

    bonding: fix bonding_masters race condition in bond unloading

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Luis

------

From 9d74c6a444452e0378a800dcc1fb79711e6fee41 Mon Sep 17 00:00:00 2001
From: "nikolay@redhat.com" <nikolay@redhat.com>
Date: Sat, 6 Apr 2013 00:54:38 +0000
Subject: [PATCH] bonding: fix bonding_masters race condition in bond unloading

commit 69b0216ac255f523556fa3d4ff030d857eaaa37f upstream.

While the bonding module is unloading, it is considered that after
rtnl_link_unregister all bond devices are destroyed but since no
synchronization mechanism exists, a new bond device can be created
via bonding_masters before unregister_pernet_subsys which would
lead to multiple problems (e.g. NULL pointer dereference, wrong RIP,
list corruption).

This patch fixes the issue by removing any bond devices left in the
netns after bonding_masters is removed from sysfs.

Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
---
 drivers/net/bonding/bond_main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

--
1.8.1.2

Patch

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 1a6b118..5fc31a1 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4870,9 +4870,18 @@  static int __net_init bond_net_init(struct net *net)
 static void __net_exit bond_net_exit(struct net *net)
 {
 	struct bond_net *bn = net_generic(net, bond_net_id);
+	struct bonding *bond, *tmp_bond;
+	LIST_HEAD(list);

 	bond_destroy_sysfs(bn);
 	bond_destroy_proc_dir(bn);
+
+	/* Kill off any bonds created after unregistering bond rtnl ops */
+	rtnl_lock();
+	list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list)
+		unregister_netdevice_queue(bond->dev, &list);
+	unregister_netdevice_many(&list);
+	rtnl_unlock();
 }

 static struct pernet_operations bond_net_ops = {