diff options
| author | Dmitry Shmidt <dimitrysh@google.com> | 2014-06-20 10:16:40 -0700 |
|---|---|---|
| committer | Dmitry Shmidt <dimitrysh@google.com> | 2014-06-20 10:16:40 -0700 |
| commit | 0c08fdcf5231617f2340cb18e45769a8ed3a1dc4 (patch) | |
| tree | 9c2f8117654e8bcbda0814207774e31afca5941f | |
| parent | 43cb578dfe2c492257636f6234a24178ed27789e (diff) | |
| download | android_external_wpa_supplicant_8-0c08fdcf5231617f2340cb18e45769a8ed3a1dc4.tar.gz android_external_wpa_supplicant_8-0c08fdcf5231617f2340cb18e45769a8ed3a1dc4.tar.bz2 android_external_wpa_supplicant_8-0c08fdcf5231617f2340cb18e45769a8ed3a1dc4.zip | |
Cumulative patch from commit 3302b7c29f42c532c815268bcdcd09e1dbe1840c
3302b7c Rate limit SA Query procedure initiation on unprotected disconnect
4075e2f EAP-GPSK: Clean up CSuite_List length validation (CID 62854)
2dbc959 EAP-FAST: Clean up TLV length validation (CID 62853)
35cbadb VHT: Remove useless validation code from Operating Mode Notification
bed7eb6 TDLS: Do not bail when failing to process IEs in Discovery Request
7e0f4f4 TDLS: Do not reject TPK M3 when failing to process IEs
Change-Id: I85ed050d7fce0ed8eb1959688171236d87264ff4
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
| -rw-r--r-- | src/ap/ieee802_11_vht.c | 14 | ||||
| -rw-r--r-- | src/eap_common/eap_fast_common.c | 2 | ||||
| -rw-r--r-- | src/eap_common/eap_fast_common.h | 2 | ||||
| -rw-r--r-- | src/eap_peer/eap_fast.c | 10 | ||||
| -rw-r--r-- | src/eap_peer/eap_gpsk.c | 18 | ||||
| -rw-r--r-- | src/eap_server/eap_server_fast.c | 10 | ||||
| -rw-r--r-- | src/rsn_supp/tdls.c | 22 | ||||
| -rw-r--r-- | wpa_supplicant/events.c | 1 | ||||
| -rw-r--r-- | wpa_supplicant/sme.c | 7 | ||||
| -rw-r--r-- | wpa_supplicant/wpa_supplicant_i.h | 1 |
10 files changed, 52 insertions, 35 deletions
diff --git a/src/ap/ieee802_11_vht.c b/src/ap/ieee802_11_vht.c index 221d9c20..437cf503 100644 --- a/src/ap/ieee802_11_vht.c +++ b/src/ap/ieee802_11_vht.c @@ -112,25 +112,11 @@ u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta, u16 set_sta_vht_opmode(struct hostapd_data *hapd, struct sta_info *sta, const u8 *vht_oper_notif) { - u8 channel_width; - if (!vht_oper_notif) { sta->flags &= ~WLAN_STA_VHT_OPMODE_ENABLED; return WLAN_STATUS_SUCCESS; } - channel_width = *vht_oper_notif & VHT_OPMODE_CHANNEL_WIDTH_MASK; - - if (channel_width != VHT_CHANWIDTH_USE_HT && - channel_width != VHT_CHANWIDTH_80MHZ && - channel_width != VHT_CHANWIDTH_160MHZ && - channel_width != VHT_CHANWIDTH_80P80MHZ && - ((*vht_oper_notif & VHT_OPMODE_CHANNEL_RxNSS_MASK) >> - VHT_OPMODE_NOTIF_RX_NSS_SHIFT) > VHT_RX_NSS_MAX_STREAMS - 1) { - sta->flags &= ~WLAN_STA_VHT_OPMODE_ENABLED; - return WLAN_STATUS_UNSPECIFIED_FAILURE; - } - sta->flags |= WLAN_STA_VHT_OPMODE_ENABLED; sta->vht_opmode = *vht_oper_notif; return WLAN_STATUS_SUCCESS; diff --git a/src/eap_common/eap_fast_common.c b/src/eap_common/eap_fast_common.c index 04b987d2..fceb1b0a 100644 --- a/src/eap_common/eap_fast_common.c +++ b/src/eap_common/eap_fast_common.c @@ -174,7 +174,7 @@ void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk) int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, - int tlv_type, u8 *pos, int len) + int tlv_type, u8 *pos, size_t len) { switch (tlv_type) { case EAP_TLV_EAP_PAYLOAD_TLV: diff --git a/src/eap_common/eap_fast_common.h b/src/eap_common/eap_fast_common.h index 89556174..d59a8450 100644 --- a/src/eap_common/eap_fast_common.h +++ b/src/eap_common/eap_fast_common.h @@ -102,6 +102,6 @@ u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn, void eap_fast_derive_eap_msk(const u8 *simck, u8 *msk); void eap_fast_derive_eap_emsk(const u8 *simck, u8 *emsk); int eap_fast_parse_tlv(struct eap_fast_tlv_parse *tlv, - int tlv_type, u8 *pos, int len); + int tlv_type, u8 *pos, size_t len); #endif /* EAP_FAST_H */ diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c index cc1f264b..b3f6a524 100644 --- a/src/eap_peer/eap_fast.c +++ b/src/eap_peer/eap_fast.c @@ -1080,7 +1080,8 @@ static int eap_fast_parse_decrypted(struct wpabuf *decrypted, struct eap_fast_tlv_parse *tlv, struct wpabuf **resp) { - int mandatory, tlv_type, len, res; + int mandatory, tlv_type, res; + size_t len; u8 *pos, *end; os_memset(tlv, 0, sizeof(*tlv)); @@ -1094,13 +1095,14 @@ static int eap_fast_parse_decrypted(struct wpabuf *decrypted, pos += 2; len = WPA_GET_BE16(pos); pos += 2; - if (pos + len > end) { + if (len > (size_t) (end - pos)) { wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow"); return -1; } wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: " - "TLV type %d length %d%s", - tlv_type, len, mandatory ? " (mandatory)" : ""); + "TLV type %d length %u%s", + tlv_type, (unsigned int) len, + mandatory ? " (mandatory)" : ""); res = eap_fast_parse_tlv(tlv, tlv_type, pos, len); if (res == -2) diff --git a/src/eap_peer/eap_gpsk.c b/src/eap_peer/eap_gpsk.c index 5b023c79..3c9cbf4a 100644 --- a/src/eap_peer/eap_gpsk.c +++ b/src/eap_peer/eap_gpsk.c @@ -236,6 +236,8 @@ static const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm, size_t *list_len, const u8 *pos, const u8 *end) { + size_t len; + if (pos == NULL) return NULL; @@ -243,23 +245,25 @@ static const u8 * eap_gpsk_process_csuite_list(struct eap_sm *sm, wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short GPSK-1 packet"); return NULL; } - *list_len = WPA_GET_BE16(pos); + len = WPA_GET_BE16(pos); pos += 2; - if (end - pos < (int) *list_len) { + if (len > (size_t) (end - pos)) { wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List overflow"); return NULL; } - if (*list_len == 0 || (*list_len % sizeof(struct eap_gpsk_csuite))) { + if (len == 0 || (len % sizeof(struct eap_gpsk_csuite))) { wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid CSuite_List len %lu", - (unsigned long) *list_len); + (unsigned long) len); return NULL; } - *list = pos; - pos += *list_len; - if (eap_gpsk_select_csuite(sm, data, *list, *list_len) < 0) + if (eap_gpsk_select_csuite(sm, data, pos, len) < 0) return NULL; + *list = pos; + *list_len = len; + pos += len; + return pos; } diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c index fcb80dc7..44a443af 100644 --- a/src/eap_server/eap_server_fast.c +++ b/src/eap_server/eap_server_fast.c @@ -1123,7 +1123,8 @@ static void eap_fast_process_phase2_eap(struct eap_sm *sm, static int eap_fast_parse_tlvs(struct wpabuf *data, struct eap_fast_tlv_parse *tlv) { - int mandatory, tlv_type, len, res; + int mandatory, tlv_type, res; + size_t len; u8 *pos, *end; os_memset(tlv, 0, sizeof(*tlv)); @@ -1136,13 +1137,14 @@ static int eap_fast_parse_tlvs(struct wpabuf *data, pos += 2; len = WPA_GET_BE16(pos); pos += 2; - if (pos + len > end) { + if (len > (size_t) (end - pos)) { wpa_printf(MSG_INFO, "EAP-FAST: TLV overflow"); return -1; } wpa_printf(MSG_DEBUG, "EAP-FAST: Received Phase 2: " - "TLV type %d length %d%s", - tlv_type, len, mandatory ? " (mandatory)" : ""); + "TLV type %d length %u%s", + tlv_type, (unsigned int) len, + mandatory ? " (mandatory)" : ""); res = eap_fast_parse_tlv(tlv, tlv_type, pos, len); if (res == -2) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 59ed2c92..652e52c6 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -1378,10 +1378,17 @@ wpa_tdls_process_discovery_request(struct wpa_sm *sm, const u8 *addr, dialog_token = buf[sizeof(struct wpa_tdls_frame)]; + /* + * Some APs will tack on a weird IE to the end of a TDLS + * discovery request packet. This needn't fail the response, + * since the required IE are verified separately. + */ if (wpa_supplicant_parse_ies(buf + sizeof(struct wpa_tdls_frame) + 1, len - (sizeof(struct wpa_tdls_frame) + 1), - &kde) < 0) - return -1; + &kde) < 0) { + wpa_printf(MSG_DEBUG, + "TDLS: Failed to parse IEs in Discovery Request - ignore as an interop workaround"); + } if (!kde.lnkid) { wpa_printf(MSG_DEBUG, "TDLS: Link ID not found in Discovery " @@ -2290,9 +2297,16 @@ static int wpa_tdls_process_tpk_m3(struct wpa_sm *sm, const u8 *src_addr, pos += 2 /* status code */ + 1 /* dialog token */; ielen = len - (pos - buf); /* start of IE in buf */ + + /* + * Don't reject the message if failing to parse IEs. The IEs we need are + * explicitly checked below. Some APs piggy-back broken IEs to the end + * of a TDLS Confirm packet, which will fail the link if we don't ignore + * this error. + */ if (wpa_supplicant_parse_ies((const u8 *) pos, ielen, &kde) < 0) { - wpa_printf(MSG_INFO, "TDLS: Failed to parse KDEs in TPK M3"); - goto error; + wpa_printf(MSG_DEBUG, + "TDLS: Failed to parse KDEs in TPK M3 - ignore as an interop workaround"); } if (kde.lnkid == NULL || kde.lnkid_len < 3 * ETH_ALEN) { diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 60da3bfc..147836b7 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1927,6 +1927,7 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, #ifdef CONFIG_SME os_memcpy(wpa_s->sme.prev_bssid, bssid, ETH_ALEN); wpa_s->sme.prev_bssid_set = 1; + wpa_s->sme.last_unprot_disconnect.sec = 0; #endif /* CONFIG_SME */ wpa_msg(wpa_s, MSG_INFO, "Associated with " MACSTR, MAC2STR(bssid)); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 82aef0d8..81a1eded 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -1344,6 +1344,7 @@ void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *da, u16 reason_code) { struct wpa_ssid *ssid; + struct os_reltime now; if (wpa_s->wpa_state != WPA_COMPLETED) return; @@ -1360,6 +1361,12 @@ void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa, if (wpa_s->sme.sa_query_count > 0) return; + os_get_reltime(&now); + if (wpa_s->sme.last_unprot_disconnect.sec && + !os_reltime_expired(&now, &wpa_s->sme.last_unprot_disconnect, 10)) + return; /* limit SA Query procedure frequency */ + wpa_s->sme.last_unprot_disconnect = now; + wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - " "possible AP/STA state mismatch - trigger SA Query"); sme_start_sa_query(wpa_s); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index c51a7030..1cb4e161 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -636,6 +636,7 @@ struct wpa_supplicant { * sa_query_count octets of pending * SA Query transaction identifiers */ struct os_reltime sa_query_start; + struct os_reltime last_unprot_disconnect; u8 sched_obss_scan; u16 obss_scan_int; u16 bss_max_idle_period; |
