]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Staging: batman-adv: Don't use net_dev after dev_put
authorSven Eckelmann <sven.eckelmann@gmx.de>
Sat, 21 Aug 2010 12:18:09 +0000 (14:18 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 26 Aug 2010 23:46:22 +0000 (16:46 -0700)
commit 51a00eaf6e008b60943af6ab68c17ac3622208dc upstream.

dev_put allows a device to be freed when all its references are dropped.
After that we are not allowed to access that information anymore. Access
to the data structure of a net_device must be surrounded a dev_hold
and ended using dev_put.

batman-adv adds a device to its own management structure in
hardif_add_interface and will release it in hardif_remove_interface.
Thus it must hold a reference all the time between those functions to
prevent any access to the already released net_device structure.

Reported-by: Tim Glaremin <Tim.Glaremin@web.de>
Signed-off-by: Sven Eckelmann <sven.eckelmann@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/batman-adv/hard-interface.c

index 92997327ae9f845fc80e8534e8390080cfa58002..d108fa1eb7330c8d3da36cdab2f944271eb49e7f 100644 (file)
@@ -194,8 +194,6 @@ static void hardif_activate_interface(struct bat_priv *bat_priv,
        if (batman_if->if_status != IF_INACTIVE)
                return;
 
-       dev_hold(batman_if->net_dev);
-
        update_mac_addresses(batman_if);
        batman_if->if_status = IF_TO_BE_ACTIVATED;
 
@@ -222,8 +220,6 @@ static void hardif_deactivate_interface(struct batman_if *batman_if)
           (batman_if->if_status != IF_TO_BE_ACTIVATED))
                return;
 
-       dev_put(batman_if->net_dev);
-
        batman_if->if_status = IF_INACTIVE;
 
        printk(KERN_INFO "batman-adv:Interface deactivated: %s\n",
@@ -321,12 +317,14 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
        if (ret != 1)
                goto out;
 
+       dev_hold(net_dev);
+
        batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
        if (!batman_if) {
                printk(KERN_ERR "batman-adv:"
                       "Can't add interface (%s): out of memory\n",
                       net_dev->name);
-               goto out;
+               goto release_dev;
        }
 
        batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
@@ -350,6 +348,8 @@ free_dev:
        kfree(batman_if->dev);
 free_if:
        kfree(batman_if);
+release_dev:
+       dev_put(net_dev);
 out:
        return NULL;
 }
@@ -378,6 +378,7 @@ static void hardif_remove_interface(struct batman_if *batman_if)
        batman_if->if_status = IF_TO_BE_REMOVED;
        list_del_rcu(&batman_if->list);
        sysfs_del_hardif(&batman_if->hardif_obj);
+       dev_put(batman_if->net_dev);
        call_rcu(&batman_if->rcu, hardif_free_interface);
 }