diff options
author | Jiri Benc <jbenc@suse.cz> | 2006-06-05 23:39:34 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-06-05 23:39:34 (GMT) |
commit | 36485707bbd9729e0c52315b173aeed9bc2303dd (patch) | |
tree | 78997f28e14702d058f90a8ba80a20abcead57d6 | |
parent | 8c893ff6abbac0c7c05b1cb9bfb6e2dfc4538c75 (diff) | |
download | linux-36485707bbd9729e0c52315b173aeed9bc2303dd.tar.xz |
[BRIDGE]: fix locking and memory leak in br_add_bridge
There are several bugs in error handling in br_add_bridge:
- when dev_alloc_name fails, allocated net_device is not freed
- unregister_netdev is called when rtnl lock is held
- free_netdev is called before netdev_run_todo has a chance to be run after
unregistering net_device
Signed-off-by: Jiri Benc <jbenc@suse.cz>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/bridge/br_if.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index ad1c7af..f5d47bf 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -300,25 +300,20 @@ int br_add_bridge(const char *name) rtnl_lock(); if (strchr(dev->name, '%')) { ret = dev_alloc_name(dev, dev->name); - if (ret < 0) - goto err1; + if (ret < 0) { + free_netdev(dev); + goto out; + } } ret = register_netdevice(dev); if (ret) - goto err2; + goto out; ret = br_sysfs_addbr(dev); if (ret) - goto err3; - rtnl_unlock(); - return 0; - - err3: - unregister_netdev(dev); - err2: - free_netdev(dev); - err1: + unregister_netdevice(dev); + out: rtnl_unlock(); return ret; } |