diff options
author | Zefan Li <lizefan@huawei.com> | 2013-06-26 03:29:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-06-26 18:36:42 -0400 |
commit | 11eb2645cbf38a08ae491bf6c602eea900ec0bb5 (patch) | |
tree | aa6e7b01ff83084985633ec26b5913fa363d2e93 | |
parent | a5cc68f3d63306d0d288f31edfc2ae6ef8ecd887 (diff) |
dlci: acquire rtnl_lock before calling __dev_get_by_name()
Otherwise the net device returned can be freed at anytime.
Signed-off-by: Li Zefan <lizefan@huawei.com>
Cc: stable@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/wan/dlci.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 147614ed86aa..1f6e0538c716 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c | |||
@@ -385,20 +385,24 @@ static int dlci_del(struct dlci_add *dlci) | |||
385 | struct net_device *master, *slave; | 385 | struct net_device *master, *slave; |
386 | int err; | 386 | int err; |
387 | 387 | ||
388 | rtnl_lock(); | ||
389 | |||
388 | /* validate slave device */ | 390 | /* validate slave device */ |
389 | master = __dev_get_by_name(&init_net, dlci->devname); | 391 | master = __dev_get_by_name(&init_net, dlci->devname); |
390 | if (!master) | 392 | if (!master) { |
391 | return -ENODEV; | 393 | err = -ENODEV; |
394 | goto out; | ||
395 | } | ||
392 | 396 | ||
393 | if (netif_running(master)) { | 397 | if (netif_running(master)) { |
394 | return -EBUSY; | 398 | err = -EBUSY; |
399 | goto out; | ||
395 | } | 400 | } |
396 | 401 | ||
397 | dlp = netdev_priv(master); | 402 | dlp = netdev_priv(master); |
398 | slave = dlp->slave; | 403 | slave = dlp->slave; |
399 | flp = netdev_priv(slave); | 404 | flp = netdev_priv(slave); |
400 | 405 | ||
401 | rtnl_lock(); | ||
402 | err = (*flp->deassoc)(slave, master); | 406 | err = (*flp->deassoc)(slave, master); |
403 | if (!err) { | 407 | if (!err) { |
404 | list_del(&dlp->list); | 408 | list_del(&dlp->list); |
@@ -407,8 +411,8 @@ static int dlci_del(struct dlci_add *dlci) | |||
407 | 411 | ||
408 | dev_put(slave); | 412 | dev_put(slave); |
409 | } | 413 | } |
414 | out: | ||
410 | rtnl_unlock(); | 415 | rtnl_unlock(); |
411 | |||
412 | return err; | 416 | return err; |
413 | } | 417 | } |
414 | 418 | ||