summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authornikolay@redhat.com <nikolay@redhat.com>2013-04-06 00:54:38 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-05-01 09:46:16 -0700
commite6b6133de54db31efc5b28b52a5892584dba409a (patch)
tree6b559f92905cc926499935ebd14a1e225d825e71 /drivers
parentbca07ae344f112d51a3ac548cfae6e100f7665f9 (diff)
bonding: fix bonding_masters race condition in bond unloading
[ Upstream commit 69b0216ac255f523556fa3d4ff030d857eaaa37f ] 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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 27cdf1f5e604..00299f5a021f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4919,9 +4919,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 = {