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 <j@w1.fi>
diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c
index c741e13..350e955 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 <j@w1.fi>
+ * Copyright (c) 2002-2015, Jouni Malinen <j@w1.fi>
  *
  * 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 @@
 			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 86b5d18..a0747b4 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -356,6 +356,8 @@
 				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 @@
 				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 cb047d0..29c3503 100644
--- a/src/common/wpa_common.h
+++ b/src/common/wpa_common.h
@@ -306,7 +306,6 @@
 } 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 @@
 	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 0d96216..5741a5b 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -511,12 +511,14 @@
 			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",