diff options
| author | Sven Eckelmann <sven.eckelmann@gmx.de> | 2010-08-21 08:18:09 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-23 21:15:37 -0400 |
| commit | 51a00eaf6e008b60943af6ab68c17ac3622208dc (patch) | |
| tree | 4333cdeeb875c4378e83c37681729619e6e1034e | |
| parent | 1189f130f89b73eecb6117c0fc5e90abbcb7faa0 (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.c | 11 |
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); |
| 347 | free_if: | 345 | free_if: |
| 348 | kfree(batman_if); | 346 | kfree(batman_if); |
| 347 | release_dev: | ||
| 348 | dev_put(net_dev); | ||
| 349 | out: | 349 | out: |
| 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 | ||
