summaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorStephen Hemminger2007-05-20 00:39:25 +0200
committerDavid S. Miller2007-05-20 00:39:25 +0200
commit9093bbb2d96d0184f037cea9b4e952a44ebe7c32 (patch)
treeac2db6fbe7ead1f6f8ef200068c0db24576bcab9 /net/core/dev.c
parent[IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr (diff)
downloadkernel-qcow2-linux-9093bbb2d96d0184f037cea9b4e952a44ebe7c32.tar.gz
kernel-qcow2-linux-9093bbb2d96d0184f037cea9b4e952a44ebe7c32.tar.xz
kernel-qcow2-linux-9093bbb2d96d0184f037cea9b4e952a44ebe7c32.zip
[NET]: Fix race condition about network device name allocation.
Kenji Kaneshige found this race between device removal and registration. On unregister it is possible for the old device to exist, because sysfs file is still open. A new device with 'eth%d' will select the same name, but sysfs kobject register will fial. The following changes the shutdown order slightly. It hold a removes the sysfs entries earlier (on unregister_netdevice), but holds a kobject reference. Then when todo runs the actual last put free happens. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index f2b61111e26d..5a7f20f78574 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3314,7 +3314,6 @@ void netdev_run_todo(void)
continue;
}
- netdev_unregister_sysfs(dev);
dev->reg_state = NETREG_UNREGISTERED;
netdev_wait_allrefs(dev);
@@ -3325,11 +3324,11 @@ void netdev_run_todo(void)
BUG_TRAP(!dev->ip6_ptr);
BUG_TRAP(!dev->dn_ptr);
- /* It must be the very last action,
- * after this 'dev' may point to freed up memory.
- */
if (dev->destructor)
dev->destructor(dev);
+
+ /* Free network device */
+ kobject_put(&dev->dev.kobj);
}
out:
@@ -3480,6 +3479,9 @@ void unregister_netdevice(struct net_device *dev)
/* Notifier chain MUST detach us from master device. */
BUG_TRAP(!dev->master);
+ /* Remove entries from sysfs */
+ netdev_unregister_sysfs(dev);
+
/* Finish processing unregister after unlock */
net_set_todo(dev);