]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix AP MLME in driver handling of FT and SA Query Action frames
authorJouni Malinen <j@w1.fi>
Sat, 9 Mar 2019 10:21:27 +0000 (12:21 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 9 Mar 2019 10:41:43 +0000 (12:41 +0200)
hostapd_action_rx() was pointing at incorrect field (Action vs.
Category) for the wpa_ft_action_rx() call and the length check for SA
Query Action frames. This resulted in those frames getting dropped as
invalid (FT) or ignored as truncated (SA Query). Fix this by pointing to
the correct place at the beginning of the frame body.

This issue had a long history. These were broken during cleanup in
commit dbfb8e82ff69 ("Remove unnecessary EVENT_RX_ACTION") which
actually fixed the initial reason for the error accidentally. It was
just that that error was needed to cancel out another earlier error..

One of the errors came from misuse of the EVENT_RX_ACTION API in commit
deca6eff7441 ("atheros: Add new IEEE 802.11r driver_ops"). That pointed
struct rx_action data/len to cover the Action frame from the Category
field to the end of the frame body while the API was documented to cover
Action field to the end of the frame body. This error was cancelled by
another error in commit 88b32a99d308 ("FT: Add FT AP support for drivers
that manage MLME internally") that called wpa_ft_action_rx() with the
struct rx_action::data field as the second argument. That argument needs
to point to the Category field, but that struct rx_action field was
supposed to point to the Action field.

Number of the Action frame handlers added into hostapd_action_rx() had
been fixed more or less accidentally after this in various other
commits, but the FT and SA Query handlers had ended up maintaining the
incorrect operations. This is now fixing those.

This seems to fix at least some cases of FT-over-DS with drivers that
use driver-based AP MLME. Such drivers might use internal SA Query
processing, so it is not clear whether that part actually fixes any real
issues.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/drv_callbacks.c

index e0c85cae64c2fd3ecc028dcd272c9c0d54d2dc1b..1c47309f1c63439bb74ee3dc73c295426271b785 100644 (file)
@@ -1085,7 +1085,7 @@ static void hostapd_action_rx(struct hostapd_data *hapd,
        if (drv_mgmt->frame_len < IEEE80211_HDRLEN + 2 + 1)
                return;
 
-       plen = drv_mgmt->frame_len - IEEE80211_HDRLEN - 1;
+       plen = drv_mgmt->frame_len - IEEE80211_HDRLEN;
 
        mgmt = (struct ieee80211_mgmt *) drv_mgmt->frame;
        fc = le_to_host16(mgmt->frame_control);
@@ -1105,9 +1105,8 @@ static void hostapd_action_rx(struct hostapd_data *hapd,
        }
 #ifdef CONFIG_IEEE80211R_AP
        if (mgmt->u.action.category == WLAN_ACTION_FT) {
-               const u8 *payload = drv_mgmt->frame + 24 + 1;
-
-               wpa_ft_action_rx(sta->wpa_sm, payload, plen);
+               wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action, plen);
+               return;
        }
 #endif /* CONFIG_IEEE80211R_AP */
 #ifdef CONFIG_IEEE80211W
@@ -1127,7 +1126,7 @@ static void hostapd_action_rx(struct hostapd_data *hapd,
        }
 #endif /* CONFIG_FST */
 #ifdef CONFIG_DPP
-       if (plen >= 1 + 4 &&
+       if (plen >= 2 + 4 &&
            mgmt->u.action.u.vs_public_action.action ==
            WLAN_PA_VENDOR_SPECIFIC &&
            WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==