Skip to content

Commit

Permalink
mac80211: Send deauth/disassoc prior to dropping STA entry
Browse files Browse the repository at this point in the history
When management frame protection (IEEE 802.11w) is used, the
deauthentication and disassociation frames must be protected whenever
the encryption keys are configured. We were removing the STA entry and
with it, the keys, just before actually sending out these frames which
meant that the frames went out unprotected. The AP will drop them in
such a case. Fix this by reordering the operations a bit so that
sta_info_destroy_addr() gets called only after
ieee80211_send_deauth_disassoc().

Signed-off-by: Jouni Malinen <j@w1.fi>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Jouni Malinen authored and John W. Linville committed Mar 31, 2010
1 parent 17e4ec1 commit e69e95d
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
netif_carrier_on(sdata->dev);
}

static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
bool remove_sta)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
struct ieee80211_local *local = sdata->local;
Expand Down Expand Up @@ -855,7 +856,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
changed |= BSS_CHANGED_BSSID;
ieee80211_bss_info_change_notify(sdata, changed);

sta_info_destroy_addr(sdata, bssid);
if (remove_sta)
sta_info_destroy_addr(sdata, bssid);
}

void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
Expand Down Expand Up @@ -968,7 +970,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)

printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);

ieee80211_set_disassoc(sdata);
ieee80211_set_disassoc(sdata, true);
ieee80211_recalc_idle(local);
mutex_unlock(&ifmgd->mtx);
/*
Expand Down Expand Up @@ -1034,7 +1036,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
sdata->name, bssid, reason_code);

ieee80211_set_disassoc(sdata);
ieee80211_set_disassoc(sdata, true);
ieee80211_recalc_idle(sdata->local);

return RX_MGMT_CFG80211_DEAUTH;
Expand Down Expand Up @@ -1064,7 +1066,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
sdata->name, mgmt->sa, reason_code);

ieee80211_set_disassoc(sdata);
ieee80211_set_disassoc(sdata, true);
ieee80211_recalc_idle(sdata->local);
return RX_MGMT_CFG80211_DISASSOC;
}
Expand Down Expand Up @@ -1712,7 +1714,7 @@ static void ieee80211_sta_work(struct work_struct *work)
printk(KERN_DEBUG "No probe response from AP %pM"
" after %dms, disconnecting.\n",
bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
ieee80211_set_disassoc(sdata);
ieee80211_set_disassoc(sdata, true);
ieee80211_recalc_idle(local);
mutex_unlock(&ifmgd->mtx);
/*
Expand Down Expand Up @@ -2014,7 +2016,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
}

/* Trying to reassociate - clear previous association state */
ieee80211_set_disassoc(sdata);
ieee80211_set_disassoc(sdata, true);
}
mutex_unlock(&ifmgd->mtx);

Expand Down Expand Up @@ -2118,7 +2120,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,

if (ifmgd->associated == req->bss) {
bssid = req->bss->bssid;
ieee80211_set_disassoc(sdata);
ieee80211_set_disassoc(sdata, true);
mutex_unlock(&ifmgd->mtx);
} else {
bool not_auth_yet = false;
Expand Down Expand Up @@ -2175,6 +2177,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
void *cookie)
{
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
u8 bssid[ETH_ALEN];

mutex_lock(&ifmgd->mtx);

Expand All @@ -2192,13 +2195,15 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
sdata->name, req->bss->bssid, req->reason_code);

ieee80211_set_disassoc(sdata);
memcpy(bssid, req->bss->bssid, ETH_ALEN);
ieee80211_set_disassoc(sdata, false);

mutex_unlock(&ifmgd->mtx);

ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
IEEE80211_STYPE_DISASSOC, req->reason_code,
cookie);
sta_info_destroy_addr(sdata, bssid);

ieee80211_recalc_idle(sdata->local);

Expand Down

0 comments on commit e69e95d

Please sign in to comment.