WPA: Fix wpa_parse_kde_ies() handling with vendor specific elements
Documentation of the return values for wpa_parse_vendor_specific() and wpa_parse_generic() were not accurate and the parsing results from these were not really handled appropriately. There is no point in calling wpa_parse_vendor_specific() if wpa_parse_generic() recognizes a KDE. Not that this would break anything in practice, but still, it looks confusing. The part about handling wpa_parse_vendor_specific() return value can, at least in theory, break some cases where an unexpectedly short KDE/vendor specific element were present and something would need to be recognized after it. That does not really happen with any standard compliant implementation and this is unlikely to cause any real harm, but it is clearer to handle this more appropriately even for any theoretical case, including misbehavior of a peer device. Instead of stopping parsing on too short vendor specific element, continue parsing the following KDEs/IEs. Skip the wpa_parse_vendor_specific() call when a KDE has been recognized. Also fix the return value documentation for wpa_parse_generic() and remove the useless return value from wpa_parse_vendor_specific(). Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
parent
1025a9052c
commit
4d9c313f2a
1 changed files with 12 additions and 16 deletions
|
@ -2655,10 +2655,9 @@ int fils_domain_name_hash(const char *domain, u8 *hash)
|
|||
* @pos: Pointer to the IE header
|
||||
* @end: Pointer to the end of the Key Data buffer
|
||||
* @ie: Pointer to parsed IE data
|
||||
* Returns: 0 on success, 1 if end mark is found, -1 on failure
|
||||
*/
|
||||
static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
|
||||
struct wpa_eapol_ie_parse *ie)
|
||||
static void wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
|
||||
struct wpa_eapol_ie_parse *ie)
|
||||
{
|
||||
unsigned int oui;
|
||||
|
||||
|
@ -2666,7 +2665,7 @@ static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
|
|||
wpa_printf(MSG_MSGDUMP,
|
||||
"Too short vendor specific IE ignored (len=%u)",
|
||||
pos[1]);
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
oui = WPA_GET_BE24(&pos[2]);
|
||||
|
@ -2683,7 +2682,6 @@ static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
|
|||
ie->wmm, ie->wmm_len);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2691,7 +2689,7 @@ static int wpa_parse_vendor_specific(const u8 *pos, const u8 *end,
|
|||
* wpa_parse_generic - Parse EAPOL-Key Key Data Generic IEs
|
||||
* @pos: Pointer to the IE header
|
||||
* @ie: Pointer to parsed IE data
|
||||
* Returns: 0 on success, 1 if end mark is found, -1 on failure
|
||||
* Returns: 0 on success, 1 if end mark is found, 2 if KDE is not recognized
|
||||
*/
|
||||
static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
|
||||
{
|
||||
|
@ -2803,7 +2801,7 @@ static int wpa_parse_generic(const u8 *pos, struct wpa_eapol_ie_parse *ie)
|
|||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2912,20 +2910,18 @@ int wpa_parse_kde_ies(const u8 *buf, size_t len, struct wpa_eapol_ie_parse *ie)
|
|||
}
|
||||
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
|
||||
ret = wpa_parse_generic(pos, ie);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret > 0) {
|
||||
if (ret == 1) {
|
||||
/* end mark found */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = wpa_parse_vendor_specific(pos, end, ie);
|
||||
if (ret < 0)
|
||||
break;
|
||||
if (ret > 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
if (ret == 2) {
|
||||
/* not a known KDE */
|
||||
wpa_parse_vendor_specific(pos, end, ie);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
} else {
|
||||
wpa_hexdump(MSG_DEBUG,
|
||||
"WPA: Unrecognized EAPOL-Key Key Data IE",
|
||||
|
|
Loading…
Reference in a new issue