From 7e07583247d0b80e3ebb5ea7585ba2d29d26dec7 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Tue, 15 Apr 2014 19:44:16 +0200 Subject: [PATCH] staging: rtl8723au: Remove struct rtw_ieee802_11_elems and related code This removes the double content tracking of data from IE elements. The relevant code to validate IEs is moved to rtw_mlme_ext.c as this is the only place where it is used. Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/core/rtw_ieee80211.c | 231 ------------------ drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 145 ++++++++++- drivers/staging/rtl8723au/include/ieee80211.h | 60 ----- 3 files changed, 139 insertions(+), 297 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c index 8fc54c806e7d..b430e10214f3 100644 --- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c @@ -884,237 +884,6 @@ u8 *rtw_get_wps_attr_content23a(u8 *wps_ie, uint wps_ielen, u16 target_attr_id, return NULL; } -static int -rtw_ieee802_11_parse_vendor_specific(u8 *pos, uint elen, - struct rtw_ieee802_11_elems *elems, - int show_errors) -{ - unsigned int oui; - - /* first 3 bytes in vendor specific information element are the IEEE - * OUI of the vendor. The following byte is used a vendor specific - * sub-type. */ - if (elen < 4) { - if (show_errors) { - DBG_8723A("short vendor specific " - "information element ignored (len =%lu)\n", - (unsigned long) elen); - } - return -1; - } - - oui = RTW_GET_BE24(pos); - switch (oui) { - case WLAN_OUI_MICROSOFT: - /* Microsoft/Wi-Fi information elements are further typed and - * subtyped */ - switch (pos[3]) { - case 1: - /* Microsoft OUI (00:50:F2) with OUI Type 1: - * real WPA information element */ - elems->wpa_ie = pos; - elems->wpa_ie_len = elen; - break; - case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ - if (elen < 5) { - DBG_8723A("short WME " - "information element ignored " - "(len =%lu)\n", - (unsigned long) elen); - return -1; - } - switch (pos[4]) { - case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: - case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: - elems->wme = pos; - elems->wme_len = elen; - break; - case WME_OUI_SUBTYPE_TSPEC_ELEMENT: - elems->wme_tspec = pos; - elems->wme_tspec_len = elen; - break; - default: - DBG_8723A("unknown WME " - "information element ignored " - "(subtype =%d len =%lu)\n", - pos[4], (unsigned long) elen); - return -1; - } - break; - case 4: - /* Wi-Fi Protected Setup (WPS) IE */ - elems->wps_ie = pos; - elems->wps_ie_len = elen; - break; - default: - DBG_8723A("Unknown Microsoft " - "information element ignored " - "(type =%d len =%lu)\n", - pos[3], (unsigned long) elen); - return -1; - } - break; - - case OUI_BROADCOM: - switch (pos[3]) { - case VENDOR_HT_CAPAB_OUI_TYPE: - elems->vendor_ht_cap = pos; - elems->vendor_ht_cap_len = elen; - break; - default: - DBG_8723A("Unknown Broadcom " - "information element ignored " - "(type =%d len =%lu)\n", - pos[3], (unsigned long) elen); - return -1; - } - break; - - default: - DBG_8723A("unknown vendor specific information " - "element ignored (vendor OUI %02x:%02x:%02x " - "len =%lu)\n", - pos[0], pos[1], pos[2], (unsigned long) elen); - return -1; - } - - return 0; -} - -/** - * ieee802_11_parse_elems - Parse information elements in management frames - * @start: Pointer to the start of IEs - * @len: Length of IE buffer in octets - * @elems: Data structure for parsed elements - * @show_errors: Whether to show parsing errors in debug log - * Returns: Parsing result - */ -enum parse_res rtw_ieee802_11_parse_elems23a(u8 *start, uint len, - struct rtw_ieee802_11_elems *elems, - int show_errors) -{ - uint left = len; - u8 *pos = start; - int unknown = 0; - - memset(elems, 0, sizeof(*elems)); - - while (left >= 2) { - u8 id, elen; - - id = *pos++; - elen = *pos++; - left -= 2; - - if (elen > left) { - if (show_errors) { - DBG_8723A("IEEE 802.11 element " - "parse failed (id =%d elen =%d " - "left =%lu)\n", - id, elen, (unsigned long) left); - } - return ParseFailed; - } - - switch (id) { - case WLAN_EID_SSID: - elems->ssid = pos; - elems->ssid_len = elen; - break; - case WLAN_EID_SUPP_RATES: - elems->supp_rates = pos; - elems->supp_rates_len = elen; - break; - case WLAN_EID_FH_PARAMS: - elems->fh_params = pos; - elems->fh_params_len = elen; - break; - case WLAN_EID_DS_PARAMS: - elems->ds_params = pos; - elems->ds_params_len = elen; - break; - case WLAN_EID_CF_PARAMS: - elems->cf_params = pos; - elems->cf_params_len = elen; - break; - case WLAN_EID_TIM: - elems->tim = pos; - elems->tim_len = elen; - break; - case WLAN_EID_IBSS_PARAMS: - elems->ibss_params = pos; - elems->ibss_params_len = elen; - break; - case WLAN_EID_CHALLENGE: - elems->challenge = pos; - elems->challenge_len = elen; - break; - case WLAN_EID_ERP_INFO: - elems->erp_info = pos; - elems->erp_info_len = elen; - break; - case WLAN_EID_EXT_SUPP_RATES: - elems->ext_supp_rates = pos; - elems->ext_supp_rates_len = elen; - break; - case WLAN_EID_VENDOR_SPECIFIC: - if (rtw_ieee802_11_parse_vendor_specific(pos, elen, - elems, - show_errors)) - unknown++; - break; - case WLAN_EID_RSN: - elems->rsn_ie = pos; - elems->rsn_ie_len = elen; - break; - case WLAN_EID_PWR_CAPABILITY: - elems->power_cap = pos; - elems->power_cap_len = elen; - break; - case WLAN_EID_SUPPORTED_CHANNELS: - elems->supp_channels = pos; - elems->supp_channels_len = elen; - break; - case WLAN_EID_MOBILITY_DOMAIN: - elems->mdie = pos; - elems->mdie_len = elen; - break; - case WLAN_EID_FAST_BSS_TRANSITION: - elems->ftie = pos; - elems->ftie_len = elen; - break; - case WLAN_EID_TIMEOUT_INTERVAL: - elems->timeout_int = pos; - elems->timeout_int_len = elen; - break; - case WLAN_EID_HT_CAPABILITY: - elems->ht_capabilities = pos; - elems->ht_capabilities_len = elen; - break; - case WLAN_EID_HT_OPERATION: - elems->ht_operation = pos; - elems->ht_operation_len = elen; - break; - default: - unknown++; - if (!show_errors) - break; - DBG_8723A("IEEE 802.11 element parse " - "ignored unknown element (id =%d elen =%d)\n", - id, elen); - break; - } - - left -= elen; - pos += elen; - } - - if (left) - return ParseFailed; - - return unknown ? ParseUnknown : ParseOK; -} - static u8 key_char2num(u8 ch) { if ((ch >= '0') && (ch <= '9')) diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index f0e24e33f5d8..8c48ca4a4905 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -1137,12 +1137,146 @@ authclnt_fail: return _FAIL; } +#ifdef CONFIG_8723AU_AP_MODE +static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen) +{ + unsigned int oui; + + /* first 3 bytes in vendor specific information element are the IEEE + * OUI of the vendor. The following byte is used a vendor specific + * sub-type. */ + if (elen < 4) { + DBG_8723A("short vendor specific information element " + "ignored (len =%i)\n", elen); + return -EINVAL; + } + + oui = RTW_GET_BE24(pos); + switch (oui) { + case WLAN_OUI_MICROSOFT: + /* Microsoft/Wi-Fi information elements are further typed and + * subtyped */ + switch (pos[3]) { + case 1: + /* Microsoft OUI (00:50:F2) with OUI Type 1: + * real WPA information element */ + break; + case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ + if (elen < 5) { + DBG_8723A("short WME information element " + "ignored (len =%i)\n", elen); + return -EINVAL; + } + switch (pos[4]) { + case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: + case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: + break; + case WME_OUI_SUBTYPE_TSPEC_ELEMENT: + break; + default: + DBG_8723A("unknown WME information element " + "ignored (subtype =%d len =%i)\n", + pos[4], elen); + return -EINVAL; + } + break; + case 4: + /* Wi-Fi Protected Setup (WPS) IE */ + break; + default: + DBG_8723A("Unknown Microsoft information element " + "ignored (type =%d len =%i)\n", + pos[3], elen); + return -EINVAL; + } + break; + + case OUI_BROADCOM: + switch (pos[3]) { + case VENDOR_HT_CAPAB_OUI_TYPE: + break; + default: + DBG_8723A("Unknown Broadcom information element " + "ignored (type =%d len =%i)\n", pos[3], elen); + return -EINVAL; + } + break; + + default: + DBG_8723A("unknown vendor specific information element " + "ignored (vendor OUI %02x:%02x:%02x len =%i)\n", + pos[0], pos[1], pos[2], elen); + return -EINVAL; + } + + return 0; +} + +static int rtw_validate_frame_ies(const u8 *start, uint len) +{ + const u8 *pos = start; + int left = len; + int unknown = 0; + + while (left >= 2) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + left -= 2; + + if (elen > left) { + DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d " + "left =%i)\n", __func__, id, elen, left); + return -EINVAL; + } + + switch (id) { + case WLAN_EID_SSID: + case WLAN_EID_SUPP_RATES: + case WLAN_EID_FH_PARAMS: + case WLAN_EID_DS_PARAMS: + case WLAN_EID_CF_PARAMS: + case WLAN_EID_TIM: + case WLAN_EID_IBSS_PARAMS: + case WLAN_EID_CHALLENGE: + case WLAN_EID_ERP_INFO: + case WLAN_EID_EXT_SUPP_RATES: + case WLAN_EID_VENDOR_SPECIFIC: + if (rtw_validate_vendor_specific_ies(pos, elen)) + unknown++; + break; + case WLAN_EID_RSN: + case WLAN_EID_PWR_CAPABILITY: + case WLAN_EID_SUPPORTED_CHANNELS: + case WLAN_EID_MOBILITY_DOMAIN: + case WLAN_EID_FAST_BSS_TRANSITION: + case WLAN_EID_TIMEOUT_INTERVAL: + case WLAN_EID_HT_CAPABILITY: + case WLAN_EID_HT_OPERATION: + default: + unknown++; + DBG_8723A("%s IEEE 802.11 ignored unknown element " + "(id =%d elen =%d)\n", __func__, id, elen); + break; + } + + left -= elen; + pos += elen; + } + + if (left) + return -EINVAL; + + return 0; +} +#endif + static int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame) { #ifdef CONFIG_8723AU_AP_MODE u16 capab_info, listen_interval; - struct rtw_ieee802_11_elems elems; struct sta_info *pstat; unsigned char reassoc; unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; @@ -1158,8 +1292,7 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame) struct sta_priv *pstapriv = &padapter->stapriv; struct sk_buff *skb = precv_frame->pkt; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data; - const u8 *p, *wpa_ie, *wps_ie; - u8 *pos; + const u8 *pos, *p, *wpa_ie, *wps_ie; u8 *pframe = skb->data; uint pkt_len = skb->len; int r; @@ -1215,8 +1348,8 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame) pstat->capability = capab_info; /* now parse all ieee802_11 ie to point to elems */ - if (rtw_ieee802_11_parse_elems23a(pos, left, &elems, 1) == - ParseFailed) { + + if (rtw_validate_frame_ies(pos, left)) { DBG_8723A("STA " MAC_FMT " sent invalid association request\n", MAC_ARG(pstat->hwaddr)); status = WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -1416,7 +1549,7 @@ OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame) pstat->uapsd_be = 0; pstat->uapsd_bk = 0; if (pmlmepriv->qospriv.qos_option) { - u8 *end = pos + left; + const u8 *end = pos + left; p = pos; for (;;) { diff --git a/drivers/staging/rtl8723au/include/ieee80211.h b/drivers/staging/rtl8723au/include/ieee80211.h index bfa7e2dbbdcc..fcbe6ba59c27 100644 --- a/drivers/staging/rtl8723au/include/ieee80211.h +++ b/drivers/staging/rtl8723au/include/ieee80211.h @@ -457,66 +457,6 @@ struct rtw_ieee80211_channel { /*, (channel)->orig_mag*/ \ /*, (channel)->orig_mpwr*/ \ -/* Parsed Information Elements */ -struct rtw_ieee802_11_elems { - u8 *ssid; - u8 ssid_len; - u8 *supp_rates; - u8 supp_rates_len; - u8 *fh_params; - u8 fh_params_len; - u8 *ds_params; - u8 ds_params_len; - u8 *cf_params; - u8 cf_params_len; - u8 *tim; - u8 tim_len; - u8 *ibss_params; - u8 ibss_params_len; - u8 *challenge; - u8 challenge_len; - u8 *erp_info; - u8 erp_info_len; - u8 *ext_supp_rates; - u8 ext_supp_rates_len; - u8 *wpa_ie; - u8 wpa_ie_len; - u8 *rsn_ie; - u8 rsn_ie_len; - u8 *wme; - u8 wme_len; - u8 *wme_tspec; - u8 wme_tspec_len; - u8 *wps_ie; - u8 wps_ie_len; - u8 *power_cap; - u8 power_cap_len; - u8 *supp_channels; - u8 supp_channels_len; - u8 *mdie; - u8 mdie_len; - u8 *ftie; - u8 ftie_len; - u8 *timeout_int; - u8 timeout_int_len; - u8 *ht_capabilities; - u8 ht_capabilities_len; - u8 *ht_operation; - u8 ht_operation_len; - u8 *vendor_ht_cap; - u8 vendor_ht_cap_len; -}; - -enum parse_res { - ParseOK = 0, - ParseUnknown = 1, - ParseFailed = -1 -}; - -enum parse_res rtw_ieee802_11_parse_elems23a(u8 *start, uint len, - struct rtw_ieee802_11_elems *elems, - int show_errors); - u8 *rtw_set_fixed_ie23a(unsigned char *pbuf, unsigned int len, unsigned char *source, unsigned int *frlen); u8 *rtw_set_ie23a(u8 *pbuf, int index, uint len, const u8 *source, uint *frlen); -- 2.34.1