diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2012-10-15 08:52:41 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-10-15 11:21:34 -0400 |
commit | 6863255bd0e48bc41ae5a066d5c771801e92735a (patch) | |
tree | 9bb64e599fb14c424480f7b4cda6abc5c7754c04 /net | |
parent | df9b42963f2d010ae3163a894ce22cf6b27cd344 (diff) |
cfg80211/mac80211: avoid state mishmash on deauth
Avoid situation when we are on associate state in mac80211 and
on disassociate state in cfg80211. This can results on crash
during modules unload (like showed on this thread:
http://marc.info/?t=134373976300001&r=1&w=2) and possibly other
problems.
Reported-by: Pedro Francisco <pedrogfrancisco@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/mlme.c | 5 | ||||
-rw-r--r-- | net/wireless/mlme.c | 12 |
2 files changed, 6 insertions, 11 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e714ed8bb19..e510a33fec7 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3549,6 +3549,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3549 | { | 3549 | { |
3550 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3550 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3551 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 3551 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
3552 | bool tx = !req->local_state_change; | ||
3552 | 3553 | ||
3553 | mutex_lock(&ifmgd->mtx); | 3554 | mutex_lock(&ifmgd->mtx); |
3554 | 3555 | ||
@@ -3565,12 +3566,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3565 | if (ifmgd->associated && | 3566 | if (ifmgd->associated && |
3566 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { | 3567 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { |
3567 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3568 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3568 | req->reason_code, true, frame_buf); | 3569 | req->reason_code, tx, frame_buf); |
3569 | } else { | 3570 | } else { |
3570 | drv_mgd_prepare_tx(sdata->local, sdata); | 3571 | drv_mgd_prepare_tx(sdata->local, sdata); |
3571 | ieee80211_send_deauth_disassoc(sdata, req->bssid, | 3572 | ieee80211_send_deauth_disassoc(sdata, req->bssid, |
3572 | IEEE80211_STYPE_DEAUTH, | 3573 | IEEE80211_STYPE_DEAUTH, |
3573 | req->reason_code, true, | 3574 | req->reason_code, tx, |
3574 | frame_buf); | 3575 | frame_buf); |
3575 | } | 3576 | } |
3576 | 3577 | ||
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 8016fee0752..904a7f36832 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -457,20 +457,14 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
457 | .reason_code = reason, | 457 | .reason_code = reason, |
458 | .ie = ie, | 458 | .ie = ie, |
459 | .ie_len = ie_len, | 459 | .ie_len = ie_len, |
460 | .local_state_change = local_state_change, | ||
460 | }; | 461 | }; |
461 | 462 | ||
462 | ASSERT_WDEV_LOCK(wdev); | 463 | ASSERT_WDEV_LOCK(wdev); |
463 | 464 | ||
464 | if (local_state_change) { | 465 | if (local_state_change && (!wdev->current_bss || |
465 | if (wdev->current_bss && | 466 | !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) |
466 | ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { | ||
467 | cfg80211_unhold_bss(wdev->current_bss); | ||
468 | cfg80211_put_bss(&wdev->current_bss->pub); | ||
469 | wdev->current_bss = NULL; | ||
470 | } | ||
471 | |||
472 | return 0; | 467 | return 0; |
473 | } | ||
474 | 468 | ||
475 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); | 469 | return rdev->ops->deauth(&rdev->wiphy, dev, &req); |
476 | } | 470 | } |