]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Fix a regression in TKIP countermeasures processing
authorJouni Malinen <j@w1.fi>
Sun, 18 Nov 2012 11:06:03 +0000 (13:06 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 18 Nov 2012 11:06:03 +0000 (13:06 +0200)
Commit 296a34f0c1730416bf2a61ab78690be43d82a3c0 changed hostapd to
remove the internal STA entry at the beginning of TKIP countermeasures.
However, this did not take into account the case where this is triggered
by an EAPOL-Key error report from a station. In such a case, WPA
authenticator state machine may continue processing after having
processed the error report. This could result in use of freed memory.
Fix this by stopping WPA processing if the STA entry got removed.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/ap/tkip_countermeasures.c
src/ap/tkip_countermeasures.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c

index dd5aa68790d69e8d3dfb1b409ca849545066e141..4a2ea0665d886bed1efc87388a851fb3cb4b9a2d 100644 (file)
@@ -66,9 +66,10 @@ void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd)
 }
 
 
-void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
+int michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
 {
        struct os_time now;
+       int ret = 0;
 
        if (addr && local) {
                struct sta_info *sta = ap_get_sta(hapd, addr);
@@ -84,7 +85,7 @@ void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
                                   "MLME-MICHAELMICFAILURE.indication "
                                   "for not associated STA (" MACSTR
                                   ") ignored", MAC2STR(addr));
-                       return;
+                       return ret;
                }
        }
 
@@ -93,8 +94,12 @@ void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local)
                hapd->michael_mic_failures = 1;
        } else {
                hapd->michael_mic_failures++;
-               if (hapd->michael_mic_failures > 1)
+               if (hapd->michael_mic_failures > 1) {
                        ieee80211_tkip_countermeasures_start(hapd);
+                       ret = 1;
+               }
        }
        hapd->michael_mic_failure = now.sec;
+
+       return ret;
 }
index f7a6624614fb418803a36cc48c0aa01a4853e623..d3eaed3cf9adb4d418d4e176b87cee0f60ede7e8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * hostapd / TKIP countermeasures
- * Copyright (c) 2002-2011, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -9,7 +9,7 @@
 #ifndef TKIP_COUNTERMEASURES_H
 #define TKIP_COUNTERMEASURES_H
 
-void michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local);
+int michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local);
 void ieee80211_tkip_countermeasures_deinit(struct hostapd_data *hapd);
 
 #endif /* TKIP_COUNTERMEASURES_H */
index 1ba83a5eb9558e981d32ec672d69daf58fb53b83..0816b25b69b121b8ad7f7717f6d828ebe30a3443 100644 (file)
@@ -54,11 +54,12 @@ static const int dot11RSNAConfigPMKReauthThreshold = 70;
 static const int dot11RSNAConfigSATimeout = 60;
 
 
-static inline void wpa_auth_mic_failure_report(
+static inline int wpa_auth_mic_failure_report(
        struct wpa_authenticator *wpa_auth, const u8 *addr)
 {
        if (wpa_auth->cb.mic_failure_report)
-               wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
+               return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
+       return 0;
 }
 
 
@@ -700,8 +701,8 @@ static int ft_check_msg_2_of_4(struct wpa_authenticator *wpa_auth,
 #endif /* CONFIG_IEEE80211R */
 
 
-static void wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
-                                    struct wpa_state_machine *sm, int group)
+static int wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
+                                   struct wpa_state_machine *sm, int group)
 {
        /* Supplicant reported a Michael MIC error */
        wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
@@ -718,7 +719,8 @@ static void wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
                                "ignore Michael MIC failure report since "
                                "pairwise cipher is not TKIP");
        } else {
-               wpa_auth_mic_failure_report(wpa_auth, sm->addr);
+               if (wpa_auth_mic_failure_report(wpa_auth, sm->addr) > 0)
+                       return 1; /* STA entry was removed */
                sm->dot11RSNAStatsTKIPRemoteMICFailures++;
                wpa_auth->dot11RSNAStatsTKIPRemoteMICFailures++;
        }
@@ -728,6 +730,7 @@ static void wpa_receive_error_report(struct wpa_authenticator *wpa_auth,
         * Authenticator may do it, let's change the keys now anyway.
         */
        wpa_request_new_ptk(sm);
+       return 0;
 }
 
 
@@ -1081,9 +1084,10 @@ continue_processing:
 #endif /* CONFIG_PEERKEY */
                        return;
                } else if (key_info & WPA_KEY_INFO_ERROR) {
-                       wpa_receive_error_report(
-                               wpa_auth, sm,
-                               !(key_info & WPA_KEY_INFO_KEY_TYPE));
+                       if (wpa_receive_error_report(
+                                   wpa_auth, sm,
+                                   !(key_info & WPA_KEY_INFO_KEY_TYPE)) > 0)
+                               return; /* STA entry was removed */
                } else if (key_info & WPA_KEY_INFO_KEY_TYPE) {
                        wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
                                        "received EAPOL-Key Request for new "
index 6bcd99ce5a29cd0e55b63e4300c4bbf08a16342a..6ab170d14a74e81defe2c7d804029634b6de570c 100644 (file)
@@ -177,7 +177,7 @@ struct wpa_auth_callbacks {
        void (*logger)(void *ctx, const u8 *addr, logger_level level,
                       const char *txt);
        void (*disconnect)(void *ctx, const u8 *addr, u16 reason);
-       void (*mic_failure_report)(void *ctx, const u8 *addr);
+       int (*mic_failure_report)(void *ctx, const u8 *addr);
        void (*set_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var,
                          int value);
        int (*get_eapol)(void *ctx, const u8 *addr, wpa_eapol_variable var);
index bdc89e4fa08e0bc483c7557b640d684c819db041..68fe5965311f4e4933a66881652bd17ad20339ba 100644 (file)
@@ -112,10 +112,10 @@ static void hostapd_wpa_auth_disconnect(void *ctx, const u8 *addr,
 }
 
 
-static void hostapd_wpa_auth_mic_failure_report(void *ctx, const u8 *addr)
+static int hostapd_wpa_auth_mic_failure_report(void *ctx, const u8 *addr)
 {
        struct hostapd_data *hapd = ctx;
-       michael_mic_failure(hapd, addr, 0);
+       return michael_mic_failure(hapd, addr, 0);
 }