From 253103681c84e605b8a9b2f2278e6b09a2d1d297 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 19 Apr 2015 11:15:58 +0300 Subject: [PATCH] FT: Fix WMM TSPEC validation in driver-based AP MLME case Commit 88b32a99d30894b2d6bb391371c442fc117edbab ('FT: Add FT AP support for drivers that manage MLME internally') added an alternative way of processing the WMM TSPEC from RIC. However, that change did not seem to include the same checks for WMM TSPEC element length that were used in the original implementation for MLME-in-hostapd case. Fix this by sharing the older implementation of copying the WMM TSPEC from RIC for both cases. It looks like the destination buffer for the response is sufficiently long for the fixed length copy, but it may have been possible to trigger a read beyond the end of the FTIE by about 50 bytes. Though, that seems to be within the buffer received for RX buffer in the case that uses this driver-based AP MLME design for FT. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth_ft.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index ef3249a3e..eeaffbf63 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -534,10 +534,8 @@ static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm, return pos; } -#ifdef NEED_AP_MLME - if (parse.wmm_tspec && sm->wpa_auth->conf.ap_mlme) { + if (parse.wmm_tspec) { struct wmm_tspec_element *tspec; - int res; if (parse.wmm_tspec_len + 2 < (int) sizeof(*tspec)) { wpa_printf(MSG_DEBUG, "FT: Too short WMM TSPEC IE " @@ -555,7 +553,13 @@ static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm, } tspec = (struct wmm_tspec_element *) pos; os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec)); - res = wmm_process_tspec(tspec); + } + +#ifdef NEED_AP_MLME + if (parse.wmm_tspec && sm->wpa_auth->conf.ap_mlme) { + int res; + + res = wmm_process_tspec((struct wmm_tspec_element *) pos); wpa_printf(MSG_DEBUG, "FT: ADDTS processing result: %d", res); if (res == WMM_ADDTS_STATUS_INVALID_PARAMETERS) rdie->status_code = @@ -566,20 +570,17 @@ static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm, else { /* TSPEC accepted; include updated TSPEC in response */ rdie->descr_count = 1; - pos += sizeof(*tspec); + pos += sizeof(struct wmm_tspec_element); } return pos; } #endif /* NEED_AP_MLME */ if (parse.wmm_tspec && !sm->wpa_auth->conf.ap_mlme) { - struct wmm_tspec_element *tspec; int res; - tspec = (struct wmm_tspec_element *) pos; - os_memcpy(tspec, parse.wmm_tspec - 2, sizeof(*tspec)); res = wpa_ft_add_tspec(sm->wpa_auth, sm->addr, pos, - sizeof(*tspec)); + sizeof(struct wmm_tspec_element)); if (res >= 0) { if (res) rdie->status_code = host_to_le16(res); @@ -587,7 +588,7 @@ static u8 * wpa_ft_process_rdie(struct wpa_state_machine *sm, /* TSPEC accepted; include updated TSPEC in * response */ rdie->descr_count = 1; - pos += sizeof(*tspec); + pos += sizeof(struct wmm_tspec_element); } return pos; }