aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIan Schram <ischram@telenet.be>2008-07-21 16:19:35 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-21 16:19:35 -0400
commit3a33cc108d11fab2a2544e2601066ba4924736aa (patch)
treef5772a2cb5d33ba43fbec8732e04953ace2c5ef5 /drivers
parent5547cd0ae8b46db9a084505239294eed9b8c8e2d (diff)
mac80211_hwsim.c: fix: BUG: unable to handle kernel NULL pointer dereference at 0000000000000370
I was looking at this out of interest, but I'm in no way familiar with the code. Looks to me that the error handling code in mac80211_hwsim is awkward. Which leads to it calling ieee80211_unregister_hw even when ieee80211_register_hw failed. The function has a for loop where it generates all simulated radios. when something fails, the error handling will call mac80211_hwsim_free which frees all simulated radios who's pointer isn't zero. However the information stored is insufficient to determine whether or not the call to ieee80211_register_hw succeeded or not for a specific radio. The included patch makes init_mac80211_hwsim clean up the current simulated radio, and then calls into mac80211_hwsim_free to clean up all the radios that did succeed. This however doesn't explain why the rate control registration failed.. build tested this, but had some problems reproducing the original problem. Signed-off-by: Ian Schram <ischram@telenet.be> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 913dc9fe08f9..5816230d58f8 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -364,8 +364,7 @@ static void mac80211_hwsim_free(void)
364 struct mac80211_hwsim_data *data; 364 struct mac80211_hwsim_data *data;
365 data = hwsim_radios[i]->priv; 365 data = hwsim_radios[i]->priv;
366 ieee80211_unregister_hw(hwsim_radios[i]); 366 ieee80211_unregister_hw(hwsim_radios[i]);
367 if (!IS_ERR(data->dev)) 367 device_unregister(data->dev);
368 device_unregister(data->dev);
369 ieee80211_free_hw(hwsim_radios[i]); 368 ieee80211_free_hw(hwsim_radios[i]);
370 } 369 }
371 } 370 }
@@ -437,7 +436,7 @@ static int __init init_mac80211_hwsim(void)
437 "mac80211_hwsim: device_create_drvdata " 436 "mac80211_hwsim: device_create_drvdata "
438 "failed (%ld)\n", PTR_ERR(data->dev)); 437 "failed (%ld)\n", PTR_ERR(data->dev));
439 err = -ENOMEM; 438 err = -ENOMEM;
440 goto failed; 439 goto failed_drvdata;
441 } 440 }
442 data->dev->driver = &mac80211_hwsim_driver; 441 data->dev->driver = &mac80211_hwsim_driver;
443 442
@@ -461,7 +460,7 @@ static int __init init_mac80211_hwsim(void)
461 if (err < 0) { 460 if (err < 0) {
462 printk(KERN_DEBUG "mac80211_hwsim: " 461 printk(KERN_DEBUG "mac80211_hwsim: "
463 "ieee80211_register_hw failed (%d)\n", err); 462 "ieee80211_register_hw failed (%d)\n", err);
464 goto failed; 463 goto failed_hw;
465 } 464 }
466 465
467 printk(KERN_DEBUG "%s: hwaddr %s registered\n", 466 printk(KERN_DEBUG "%s: hwaddr %s registered\n",
@@ -479,9 +478,9 @@ static int __init init_mac80211_hwsim(void)
479 rtnl_lock(); 478 rtnl_lock();
480 479
481 err = dev_alloc_name(hwsim_mon, hwsim_mon->name); 480 err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
482 if (err < 0) { 481 if (err < 0)
483 goto failed_mon; 482 goto failed_mon;
484 } 483
485 484
486 err = register_netdevice(hwsim_mon); 485 err = register_netdevice(hwsim_mon);
487 if (err < 0) 486 if (err < 0)
@@ -494,7 +493,14 @@ static int __init init_mac80211_hwsim(void)
494failed_mon: 493failed_mon:
495 rtnl_unlock(); 494 rtnl_unlock();
496 free_netdev(hwsim_mon); 495 free_netdev(hwsim_mon);
496 mac80211_hwsim_free();
497 return err;
497 498
499failed_hw:
500 device_unregister(data->dev);
501failed_drvdata:
502 ieee80211_free_hw(hw);
503 hwsim_radios[i] = 0;
498failed: 504failed:
499 mac80211_hwsim_free(); 505 mac80211_hwsim_free();
500 return err; 506 return err;