diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-07-30 19:35:46 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-31 05:28:13 -0400 |
commit | 7f988eab57bd22884bbc452fb04c6c18738666b3 (patch) | |
tree | d679707a0251dc3d399de7e52c5499dff521c86e /net | |
parent | 7ce1b0edcb11f90f6fc5e0ceecff467f329889a0 (diff) |
[NET]: Take dev_base_lock when moving device name hash list entry
When we added name-based hashing the dev_base_lock was designated as the
lock to take when changing the name hash list. Unfortunately, because
it was a preexisting lock that just happened to be taken in the right
spots we neglected to take it in dev_change_name.
The race can affect calles of __dev_get_by_name that do so without taking
the RTNL. They may end up walking down the wrong hash chain and end up
missing the device that they're looking for.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 7bfea5e9030e..346cbf66534e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -839,8 +839,12 @@ int dev_change_name(struct net_device *dev, char *newname) | |||
839 | strlcpy(dev->name, newname, IFNAMSIZ); | 839 | strlcpy(dev->name, newname, IFNAMSIZ); |
840 | 840 | ||
841 | device_rename(&dev->dev, dev->name); | 841 | device_rename(&dev->dev, dev->name); |
842 | |||
843 | write_lock_bh(&dev_base_lock); | ||
842 | hlist_del(&dev->name_hlist); | 844 | hlist_del(&dev->name_hlist); |
843 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); | 845 | hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); |
846 | write_unlock_bh(&dev_base_lock); | ||
847 | |||
844 | raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); | 848 | raw_notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); |
845 | 849 | ||
846 | return err; | 850 | return err; |