From ae7a42bde24f13d2a1324538713c50ca3afc9581 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 19 Apr 2015 16:28:35 +0300 Subject: [PATCH] FT: Check FT, MD, and Timeout Interval length in the parser All the existing users of these elements were already validating the element length. However, it is clearer to validate this already at the parser for extra layer of protection for any future changes. Signed-off-by: Jouni Malinen --- src/common/ieee802_11_common.c | 9 ++++++++- src/common/wpa_common.c | 4 ++++ src/common/wpa_common.h | 2 -- src/rsn_supp/wpa_ie.c | 6 ++++-- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c index c741e13b0..350e95580 100644 --- a/src/common/ieee802_11_common.c +++ b/src/common/ieee802_11_common.c @@ -1,6 +1,6 @@ /* * IEEE 802.11 Common routines - * Copyright (c) 2002-2013, Jouni Malinen + * Copyright (c) 2002-2015, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -10,6 +10,7 @@ #include "common.h" #include "defs.h" +#include "wpa_common.h" #include "ieee802_11_defs.h" #include "ieee802_11_common.h" @@ -245,14 +246,20 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, elems->supp_channels_len = elen; break; case WLAN_EID_MOBILITY_DOMAIN: + if (elen < sizeof(struct rsn_mdie)) + break; elems->mdie = pos; elems->mdie_len = elen; break; case WLAN_EID_FAST_BSS_TRANSITION: + if (elen < sizeof(struct rsn_ftie)) + break; elems->ftie = pos; elems->ftie_len = elen; break; case WLAN_EID_TIMEOUT_INTERVAL: + if (elen != 5) + break; elems->timeout_int = pos; elems->timeout_int_len = elen; break; diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 86b5d189c..a0747b4ba 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -356,6 +356,8 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, parse->rsn_pmkid = data.pmkid; break; case WLAN_EID_MOBILITY_DOMAIN: + if (pos[1] < sizeof(struct rsn_mdie)) + return -1; parse->mdie = pos + 2; parse->mdie_len = pos[1]; break; @@ -368,6 +370,8 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, return -1; break; case WLAN_EID_TIMEOUT_INTERVAL: + if (pos[1] != 5) + break; parse->tie = pos + 2; parse->tie_len = pos[1]; break; diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index cb047d04b..29c3503c8 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -306,7 +306,6 @@ struct wpa_igtk_kde { } STRUCT_PACKED; #endif /* CONFIG_IEEE80211W */ -#ifdef CONFIG_IEEE80211R struct rsn_mdie { u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; u8 ft_capab; @@ -334,7 +333,6 @@ struct rsn_rdie { le16 status_code; } STRUCT_PACKED; -#endif /* CONFIG_IEEE80211R */ #ifdef _MSC_VER #pragma pack(pop) diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index 0d96216d2..5741a5bb7 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -511,12 +511,14 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len, ie->rsn_ie_len = pos[1] + 2; wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key", ie->rsn_ie, ie->rsn_ie_len); - } else if (*pos == WLAN_EID_MOBILITY_DOMAIN) { + } else if (*pos == WLAN_EID_MOBILITY_DOMAIN && + pos[1] >= sizeof(struct rsn_mdie)) { ie->mdie = pos; ie->mdie_len = pos[1] + 2; wpa_hexdump(MSG_DEBUG, "WPA: MDIE in EAPOL-Key", ie->mdie, ie->mdie_len); - } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION) { + } else if (*pos == WLAN_EID_FAST_BSS_TRANSITION && + pos[1] >= sizeof(struct rsn_ftie)) { ie->ftie = pos; ie->ftie_len = pos[1] + 2; wpa_hexdump(MSG_DEBUG, "WPA: FTIE in EAPOL-Key",