aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Eckelmann <sven.eckelmann@gmx.de>2010-08-21 08:18:09 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-23 21:15:37 -0400
commit51a00eaf6e008b60943af6ab68c17ac3622208dc (patch)
tree4333cdeeb875c4378e83c37681729619e6e1034e
parent1189f130f89b73eecb6117c0fc5e90abbcb7faa0 (diff)
Staging: batman-adv: Don't use net_dev after dev_put
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> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/batman-adv/hard-interface.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c
index 892166b86dd8..d08491ed5455 100644
--- a/drivers/staging/batman-adv/hard-interface.c
+++ b/drivers/staging/batman-adv/hard-interface.c
@@ -194,8 +194,6 @@ static void hardif_activate_interface(struct net_device *net_dev,
194 if (batman_if->if_status != IF_INACTIVE) 194 if (batman_if->if_status != IF_INACTIVE)
195 return; 195 return;
196 196
197 dev_hold(batman_if->net_dev);
198
199 update_mac_addresses(batman_if); 197 update_mac_addresses(batman_if);
200 batman_if->if_status = IF_TO_BE_ACTIVATED; 198 batman_if->if_status = IF_TO_BE_ACTIVATED;
201 199
@@ -222,8 +220,6 @@ static void hardif_deactivate_interface(struct net_device *net_dev,
222 (batman_if->if_status != IF_TO_BE_ACTIVATED)) 220 (batman_if->if_status != IF_TO_BE_ACTIVATED))
223 return; 221 return;
224 222
225 dev_put(batman_if->net_dev);
226
227 batman_if->if_status = IF_INACTIVE; 223 batman_if->if_status = IF_INACTIVE;
228 224
229 bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); 225 bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev);
@@ -318,11 +314,13 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev)
318 if (ret != 1) 314 if (ret != 1)
319 goto out; 315 goto out;
320 316
317 dev_hold(net_dev);
318
321 batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); 319 batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC);
322 if (!batman_if) { 320 if (!batman_if) {
323 pr_err("Can't add interface (%s): out of memory\n", 321 pr_err("Can't add interface (%s): out of memory\n",
324 net_dev->name); 322 net_dev->name);
325 goto out; 323 goto release_dev;
326 } 324 }
327 325
328 batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); 326 batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC);
@@ -346,6 +344,8 @@ free_dev:
346 kfree(batman_if->dev); 344 kfree(batman_if->dev);
347free_if: 345free_if:
348 kfree(batman_if); 346 kfree(batman_if);
347release_dev:
348 dev_put(net_dev);
349out: 349out:
350 return NULL; 350 return NULL;
351} 351}
@@ -374,6 +374,7 @@ static void hardif_remove_interface(struct batman_if *batman_if)
374 batman_if->if_status = IF_TO_BE_REMOVED; 374 batman_if->if_status = IF_TO_BE_REMOVED;
375 list_del_rcu(&batman_if->list); 375 list_del_rcu(&batman_if->list);
376 sysfs_del_hardif(&batman_if->hardif_obj); 376 sysfs_del_hardif(&batman_if->hardif_obj);
377 dev_put(batman_if->net_dev);
377 call_rcu(&batman_if->rcu, hardif_free_interface); 378 call_rcu(&batman_if->rcu, hardif_free_interface);
378} 379}
379 380