Patchwork [2/2] bonding: fix bonding_masters race condition in bond unloading

login
register
mail settings
Submitter Nikolay Aleksandrov
Date April 6, 2013, 10:54 a.m.
Message ID <1365245678-4455-2-git-send-email-nikolay@redhat.com>
Download mbox | patch
Permalink /patch/234326/
State Accepted
Delegated to: David Miller
Headers show

Comments

Nikolay Aleksandrov - April 6, 2013, 10:54 a.m.
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>
---
 drivers/net/bonding/bond_main.c | 9 +++++++++
 1 file changed, 9 insertions(+)
Veaceslav Falico - April 6, 2013, 1:50 p.m.
On Sat, Apr 06, 2013 at 12:54:38PM +0200, Nikolay Aleksandrov wrote:
>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>
>---
> drivers/net/bonding/bond_main.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>

I'm still thinking that's it's not the best way of fixing it
(remove_devices(); remove_sysfs(); remove_devices()) - but given that I
can't come up with anything better and my first fix didn't actually work -
I'm ok with your patch.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Veaceslav Falico - April 8, 2013, 9:24 a.m.
On Sat, Apr 06, 2013 at 12:54:38PM +0200, Nikolay Aleksandrov wrote:
>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>
>---
> drivers/net/bonding/bond_main.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>

Given that this bug is in net tree and we really need a fix to continue
development, adding a second device removal loop is not a big deal
actually, and this can be addressed correctly later in net-next. It's a
really rare bug anyway, and the second loop most of the time would be a
simple no-op, as Nikolay correctly stated.

Acked-by: Veaceslav Falico <vfalico@redhat.com>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller - April 8, 2013, 8:45 p.m.
From: Nikolay Aleksandrov <nikolay@redhat.com>
Date: Sat,  6 Apr 2013 12:54:38 +0200

> 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>

Applied.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a51241b..07401a3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4846,9 +4846,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 = {