P2P: Fix segfault when PBC overlap is detected

If a separate P2P group interface is used, PBC overlap during group
formation causes the group interface to be removed, which ends up with
the interface context becoming invalid. Fix this by scheduling a timeout
to process the PBC overlap and interface removal instead of removing the
interface directly before the connection operation has returned.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
This commit is contained in:
Avraham Stern 2014-03-27 08:58:30 +02:00 committed by Jouni Malinen
parent cf15b15cc1
commit ace0fbdb69
4 changed files with 14 additions and 11 deletions

View file

@ -1069,8 +1069,12 @@ int wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP wpa_msg(wpa_s, MSG_INFO, WPS_EVENT_OVERLAP
"PBC session overlap"); "PBC session overlap");
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
if (wpas_p2p_notif_pbc_overlap(wpa_s) == 1) if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT ||
wpa_s->p2p_in_provisioning) {
eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb,
wpa_s, NULL);
return -1; return -1;
}
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */
#ifdef CONFIG_WPS #ifdef CONFIG_WPS

View file

@ -6392,6 +6392,13 @@ int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s)
} }
void wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
wpas_p2p_notif_pbc_overlap(wpa_s);
}
void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s) void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s)
{ {
struct p2p_channels chan, cli_chan; struct p2p_channels chan, cli_chan;

View file

@ -158,6 +158,7 @@ int wpas_p2p_nfc_report_handover(struct wpa_supplicant *wpa_s, int init,
const struct wpabuf *req, const struct wpabuf *req,
const struct wpabuf *sel, int forced_freq); const struct wpabuf *sel, int forced_freq);
int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled); int wpas_p2p_nfc_tag_enabled(struct wpa_supplicant *wpa_s, int enabled);
void wpas_p2p_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx);
#ifdef CONFIG_P2P #ifdef CONFIG_P2P
int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s); int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s);

View file

@ -510,15 +510,6 @@ static int wpa_supplicant_wps_cred(void *ctx,
} }
#ifdef CONFIG_P2P
static void wpas_wps_pbc_overlap_cb(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
wpas_p2p_notif_pbc_overlap(wpa_s);
}
#endif /* CONFIG_P2P */
static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s, static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
struct wps_event_m2d *m2d) struct wps_event_m2d *m2d)
{ {
@ -537,7 +528,7 @@ static void wpa_supplicant_wps_event_m2d(struct wpa_supplicant *wpa_s,
* Notify P2P from eloop timeout to avoid issues with the * Notify P2P from eloop timeout to avoid issues with the
* interface getting removed while processing a message. * interface getting removed while processing a message.
*/ */
eloop_register_timeout(0, 0, wpas_wps_pbc_overlap_cb, wpa_s, eloop_register_timeout(0, 0, wpas_p2p_pbc_overlap_cb, wpa_s,
NULL); NULL);
} }
#endif /* CONFIG_P2P */ #endif /* CONFIG_P2P */