Clear WPA and EAPOL state machine config pointer on network removal
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 27 Jun 2011 16:02:24 +0000 (19:02 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 27 Jun 2011 16:02:24 +0000 (19:02 +0300)
Make sure that the WPA and EAPOL state machines do not hold a pointer
to a network configuration that is about to be freed. This can fix
potential issues with references to freed memory.

wpa_supplicant/ctrl_iface.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/wps_supplicant.c

index cbc6fef..730e607 100644 (file)
@@ -1393,6 +1393,8 @@ static int wpa_supplicant_ctrl_iface_remove_network(
                }
                if (wpa_s->current_ssid) {
                        eapol_sm_invalidate_cached_session(wpa_s->eapol);
+                       wpa_sm_set_config(wpa_s->wpa, NULL);
+                       eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
                        wpa_supplicant_disassociate(wpa_s,
                                                    WLAN_REASON_DEAUTH_LEAVING);
                }
@@ -1416,6 +1418,8 @@ static int wpa_supplicant_ctrl_iface_remove_network(
                 * removed.
                 */
                eapol_sm_invalidate_cached_session(wpa_s->eapol);
+               wpa_sm_set_config(wpa_s->wpa, NULL);
+               eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
 
                wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
        }
index 550173a..c34a28c 100644 (file)
@@ -23,6 +23,8 @@
 #include "p2p/p2p.h"
 #include "ap/hostapd.h"
 #include "ap/p2p_hostapd.h"
+#include "eapol_supp/eapol_supp_sm.h"
+#include "rsn_supp/wpa.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "ap.h"
@@ -293,8 +295,11 @@ static void wpas_p2p_group_delete(struct wpa_supplicant *wpa_s)
                     ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION ||
                     (ssid->key_mgmt & WPA_KEY_MGMT_WPS))) {
                int id = ssid->id;
-               if (ssid == wpa_s->current_ssid)
+               if (ssid == wpa_s->current_ssid) {
+                       wpa_sm_set_config(wpa_s->wpa, NULL);
+                       eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
                        wpa_s->current_ssid = NULL;
+               }
                /*
                 * Networks objects created during any P2P activities are not
                 * exposed out as they might/will confuse certain non-P2P aware
index b75c6ef..e3388bd 100644 (file)
@@ -24,6 +24,7 @@
 #include "common/wpa_ctrl.h"
 #include "eap_common/eap_wsc_common.h"
 #include "eap_peer/eap.h"
+#include "eapol_supp/eapol_supp_sm.h"
 #include "rsn_supp/wpa.h"
 #include "config.h"
 #include "wpa_supplicant_i.h"
@@ -673,7 +674,9 @@ enum wps_request_type wpas_wps_get_req_type(struct wpa_ssid *ssid)
 static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
 {
        int id;
-       struct wpa_ssid *ssid, *remove_ssid = NULL;
+       struct wpa_ssid *ssid, *remove_ssid = NULL, *prev_current;
+
+       prev_current = wpa_s->current_ssid;
 
        eloop_cancel_timeout(wpas_wps_timeout, wpa_s, NULL);
 
@@ -692,6 +695,11 @@ static void wpas_clear_wps(struct wpa_supplicant *wpa_s)
                        id = -1;
                ssid = ssid->next;
                if (id >= 0) {
+                       if (prev_current == remove_ssid) {
+                               wpa_sm_set_config(wpa_s->wpa, NULL);
+                               eapol_sm_notify_config(wpa_s->eapol, NULL,
+                                                      NULL);
+                       }
                        wpas_notify_network_removed(wpa_s, remove_ssid);
                        wpa_config_remove_network(wpa_s->conf, id);
                }