From 5cbd88d921b15cc5e0bf8d0bb9f60f59fd1ab195 Mon Sep 17 00:00:00 2001 From: Jithu Jance Date: Mon, 24 Oct 2011 23:37:39 +0300 Subject: [PATCH] P2P: Fix wpa_supplicant crash on P2P WPS PBC overlap case Once PBC overlap detected when using dynamic group interfaces, the wpa_s corresponding to P2P group interface is freed. This patch avoids accessing the wpa_s data structure after it is freed. This fixes a possible crash in P2P client role in such a case. --- wpa_supplicant/events.c | 20 +++++++++++++------- wpa_supplicant/wpa_supplicant_i.h | 6 +++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 8bf0ee389..74e3bb58f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -819,22 +819,22 @@ static void wpa_supplicant_req_new_scan(struct wpa_supplicant *wpa_s, } -void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, - struct wpa_bss *selected, - struct wpa_ssid *ssid) +int wpa_supplicant_connect(struct wpa_supplicant *wpa_s, + struct wpa_bss *selected, + struct wpa_ssid *ssid) { if (wpas_wps_scan_pbc_overlap(wpa_s, selected, ssid)) { wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP "PBC session overlap"); #ifdef CONFIG_P2P if (wpas_p2p_notif_pbc_overlap(wpa_s) == 1) - return; + return -1; #endif /* CONFIG_P2P */ #ifdef CONFIG_WPS wpas_wps_cancel(wpa_s); #endif /* CONFIG_WPS */ - return; + return -1; } /* @@ -850,7 +850,7 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, 0))) { if (wpa_supplicant_scard_init(wpa_s, ssid)) { wpa_supplicant_req_new_scan(wpa_s, 10, 0); - return; + return 0; } wpa_msg(wpa_s, MSG_DEBUG, "Request association: " "reassociate: %d selected: "MACSTR " bssid: " MACSTR @@ -863,6 +863,8 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, wpa_dbg(wpa_s, MSG_DEBUG, "Already associated with the " "selected AP"); } + + return 0; } @@ -1088,7 +1090,11 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, wpa_scan_results_free(scan_res); if (skip) return 0; - wpa_supplicant_connect(wpa_s, selected, ssid); + + if (wpa_supplicant_connect(wpa_s, selected, ssid) < 0) { + wpa_dbg(wpa_s, MSG_DEBUG, "Connect failed"); + return -1; + } wpa_supplicant_rsn_preauth_scan_results(wpa_s); } else { wpa_scan_results_free(scan_res); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index c247a8c5b..a11db03a8 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -581,9 +581,9 @@ int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s); /* events.c */ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s); -void wpa_supplicant_connect(struct wpa_supplicant *wpa_s, - struct wpa_bss *selected, - struct wpa_ssid *ssid); +int wpa_supplicant_connect(struct wpa_supplicant *wpa_s, + struct wpa_bss *selected, + struct wpa_ssid *ssid); /* eap_register.c */ int eap_register_methods(void);