From 3fbb1d543d31301b3a127fed2543a44421537749 Mon Sep 17 00:00:00 2001 From: mentor Date: Tue, 13 Nov 2007 17:45:58 +0000 Subject: [PATCH] Modify ieee80211_saveie and ieee80211_saveath(ewww) to take a NULL source parameter, and to cleanup in this case. On reception of an Associatiion request, always save IEs correctly (i.e., cleanup up any no longer valid IEs in the case that no new, valid IE is received). Ticket: http://madwifi.org/ticket/1188 Original Patch: Signed-Off-By: Bas git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@2847 0192ed92-7a03-0410-a25b-9323aeb14dbd --- net80211/ieee80211_input.c | 109 +++++++++++-------------------------- 1 file changed, 33 insertions(+), 76 deletions(-) diff --git a/net80211/ieee80211_input.c b/net80211/ieee80211_input.c index 6364e4c..575e949 100644 --- a/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c @@ -2059,19 +2059,19 @@ ieee80211_parse_rsn(struct ieee80211vap *vap, u_int8_t *frm, return 0; } +/* Record information element for later use. */ void ieee80211_saveie(u_int8_t **iep, const u_int8_t *ie) { u_int ielen = ie[1] + 2; - /* - * Record information element for later use. - */ - if (*iep == NULL || (*iep)[1] != ie[1]) { + if ((*iep == NULL) || (ie == NULL) || ((*iep)[1] != ie[1])) { if (*iep != NULL) FREE(*iep, M_DEVBUF); - MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT); + *iep = NULL; + if (ie != NULL) + MALLOC(*iep, void*, ielen, M_DEVBUF, M_NOWAIT); } - if (*iep != NULL) + if ((*iep != NULL) && (ie != NULL)) memcpy(*iep, ie, ielen); } EXPORT_SYMBOL(ieee80211_saveie); @@ -2248,10 +2248,15 @@ ieee80211_saveath(struct ieee80211_node *ni, u_int8_t *ie) const struct ieee80211_ie_athAdvCap *athIe = (const struct ieee80211_ie_athAdvCap *) ie; - ni->ni_ath_flags = athIe->athAdvCap_capability; - if (ni->ni_ath_flags & IEEE80211_ATHC_COMP) - ni->ni_ath_defkeyindex = LE_READ_2(&athIe->athAdvCap_defKeyIndex); ieee80211_saveie(&ni->ni_ath_ie, ie); + if (athIe != NULL) { + ni->ni_ath_flags = athIe->athAdvCap_capability; + if (ni->ni_ath_flags & IEEE80211_ATHC_COMP) + ni->ni_ath_defkeyindex = LE_READ_2(&athIe->athAdvCap_defKeyIndex); + } else { + ni->ni_ath_flags = 0; + ni->ni_ath_defkeyindex = IEEE80211_INVAL_DEFKEY; + } } struct ieee80211_channel * @@ -3188,10 +3193,8 @@ ieee80211_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, ether_sprintf(wh->i_addr2)); break; case IEEE80211_ELEMID_VENDOR: - /* don't override RSN element - * XXX: actually the driver should report both WPA versions, - * so wpa_supplicant can choose and also detect downgrade attacks - */ + /* NB: Provide all IEs for wpa_supplicant, so + * it can handle downgrade attacks, etc. */ if (iswpaoui(frm) && !wpa) { if (vap->iv_flags & IEEE80211_F_WPA1) wpa = frm; @@ -3210,6 +3213,7 @@ ieee80211_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, } if (frm > efrm) return; + IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE); IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN); IEEE80211_VERIFY_SSID(vap->iv_bss, ssid); @@ -3242,13 +3246,9 @@ ieee80211_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, } if (rsn != NULL) { - /* - * Parse WPA information element. Note that - * we initialize the param block from the node - * state so that information in the IE overrides - * our defaults. The resulting parameters are - * installed below after the association is assured. - */ + /* Initialise values to node defaults, which are then + * overwritten by values in the IE. These are + * installed once association is complete. */ rsn_parm = ni->ni_rsn; if (rsn[0] != IEEE80211_ELEMID_RSN) reason = ieee80211_parse_wpa(vap, rsn, &rsn_parm, wh); @@ -3276,7 +3276,7 @@ ieee80211_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, FREE(ni->ni_challenge, M_DEVBUF); ni->ni_challenge = NULL; } - /* 802.11 spec says to ignore station's privacy bit */ + /* 802.11 spec. says to ignore station's privacy bit */ if ((capinfo & IEEE80211_CAPINFO_ESS) == 0) { IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_ANY, wh->i_addr2, "deny %s request, capability mismatch 0x%x", @@ -3332,62 +3332,19 @@ ieee80211_recv_mgmt(struct ieee80211_node *ni, struct sk_buff *skb, ni->ni_chan = ic->ic_curchan; ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; ni->ni_fhindex = vap->iv_bss->ni_fhindex; - if (wpa != NULL) { - /* - * Record WPA/RSN parameters for station, mark - * node as using WPA and record information element - * for applications that require it. - */ - ieee80211_saveie(&ni->ni_wpa_ie, wpa); - } else if (ni->ni_wpa_ie != NULL) { - /* - * Flush any state from a previous association. - */ - FREE(ni->ni_wpa_ie, M_DEVBUF); - ni->ni_wpa_ie = NULL; - } - if (rsn != NULL) { - /* - * Record WPA/RSN parameters for station, mark - * node as using WPA and record information element - * for applications that require it. - */ - ni->ni_rsn = rsn_parm; - ieee80211_saveie(&ni->ni_rsn_ie, rsn); - } else if (ni->ni_rsn_ie != NULL) { - /* - * Flush any state from a previous association. - */ - FREE(ni->ni_rsn_ie, M_DEVBUF); - ni->ni_rsn_ie = NULL; - } - if (wme != NULL) { - /* - * Record WME parameters for station, mark node - * as capable of QoS and record information - * element for applications that require it. - */ - ieee80211_saveie(&ni->ni_wme_ie, wme); - if (ieee80211_parse_wmeie(wme, wh, ni) > 0) + + /* WPA */ + ieee80211_saveie(&ni->ni_wpa_ie, wpa); + /* RSN */ + ni->ni_rsn = rsn_parm; + ieee80211_saveie(&ni->ni_rsn_ie, rsn); + /* WME - including QoS flag */ + ieee80211_saveie(&ni->ni_wme_ie, wme); + ni->ni_flags &= ~IEEE80211_NODE_QOS; + if ((wme != NULL) && (ieee80211_parse_wmeie(wme, wh, ni) > 0)) ni->ni_flags |= IEEE80211_NODE_QOS; - } else if (ni->ni_wme_ie != NULL) { - /* - * Flush any state from a previous association. - */ - FREE(ni->ni_wme_ie, M_DEVBUF); - ni->ni_wme_ie = NULL; - ni->ni_flags &= ~IEEE80211_NODE_QOS; - } - if (ath != NULL) - ieee80211_saveath(ni, ath); - else if (ni->ni_ath_ie != NULL) { - /* - * Flush any state from a previous association. - */ - FREE(ni->ni_ath_ie, M_DEVBUF); - ni->ni_ath_ie = NULL; - ni->ni_ath_flags = 0; - } + + ieee80211_saveath(ni, ath); /* Send TGf L2UF frame on behalf of newly associated station */ ieee80211_deliver_l2uf(ni);