dlci: acquire rtnl_lock before calling __dev_get_by_name()
authorZefan Li <lizefan@huawei.com>
Wed, 26 Jun 2013 07:29:54 +0000 (15:29 +0800)
committerBen Hutchings <ben@decadent.org.uk>
Sat, 27 Jul 2013 04:34:21 +0000 (05:34 +0100)
commit 11eb2645cbf38a08ae491bf6c602eea900ec0bb5 upstream.

Otherwise the net device returned can be freed at anytime.

Signed-off-by: Li Zefan <lizefan@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/net/wan/dlci.c

index 48ab38a..fa8d72c 100644 (file)
@@ -386,20 +386,24 @@ static int dlci_del(struct dlci_add *dlci)
        struct net_device       *master, *slave;
        int                     err;
 
        struct net_device       *master, *slave;
        int                     err;
 
+       rtnl_lock();
+
        /* validate slave device */
        master = __dev_get_by_name(&init_net, dlci->devname);
        /* validate slave device */
        master = __dev_get_by_name(&init_net, dlci->devname);
-       if (!master)
-               return -ENODEV;
+       if (!master) {
+               err = -ENODEV;
+               goto out;
+       }
 
        if (netif_running(master)) {
 
        if (netif_running(master)) {
-               return -EBUSY;
+               err = -EBUSY;
+               goto out;
        }
 
        dlp = netdev_priv(master);
        slave = dlp->slave;
        flp = netdev_priv(slave);
 
        }
 
        dlp = netdev_priv(master);
        slave = dlp->slave;
        flp = netdev_priv(slave);
 
-       rtnl_lock();
        err = (*flp->deassoc)(slave, master);
        if (!err) {
                list_del(&dlp->list);
        err = (*flp->deassoc)(slave, master);
        if (!err) {
                list_del(&dlp->list);
@@ -408,8 +412,8 @@ static int dlci_del(struct dlci_add *dlci)
 
                dev_put(slave);
        }
 
                dev_put(slave);
        }
+out:
        rtnl_unlock();
        rtnl_unlock();
-
        return err;
 }
 
        return err;
 }