P2P: Fix group interface removal through interface ctrl_iface
It was possible to issue the P2P_GROUP_REMOVE command through the per-interface control interface. This resulted in freed memory getting accessed when trying to send the control interface response to the operation that ended up deleting the group interface. Fix this by postponing the removal operation until the caller has returned. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
19d3a6e364
commit
f2b3acc9d7
1 changed files with 35 additions and 2 deletions
|
@ -426,6 +426,37 @@ static struct wpa_supplicant * wpas_get_p2p_group(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void run_wpas_p2p_disconnect(void *eloop_ctx, void *timeout_ctx)
|
||||||
|
{
|
||||||
|
struct wpa_supplicant *wpa_s = eloop_ctx;
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"P2P: Complete previously requested removal of %s",
|
||||||
|
wpa_s->ifname);
|
||||||
|
wpas_p2p_disconnect(wpa_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpas_p2p_disconnect_safely(struct wpa_supplicant *wpa_s,
|
||||||
|
struct wpa_supplicant *calling_wpa_s)
|
||||||
|
{
|
||||||
|
if (calling_wpa_s == wpa_s &&
|
||||||
|
wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
|
||||||
|
/*
|
||||||
|
* The calling wpa_s instance is going to be removed. Do that
|
||||||
|
* from an eloop callback to keep the instance available until
|
||||||
|
* the caller has returned. This my be needed, e.g., to provide
|
||||||
|
* control interface responses on the per-interface socket.
|
||||||
|
*/
|
||||||
|
if (eloop_register_timeout(0, 0, run_wpas_p2p_disconnect,
|
||||||
|
wpa_s, NULL) < 0)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wpas_p2p_disconnect(wpa_s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
|
static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
|
||||||
enum p2p_group_removal_reason removal_reason)
|
enum p2p_group_removal_reason removal_reason)
|
||||||
{
|
{
|
||||||
|
@ -545,6 +576,7 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
|
||||||
global = wpa_s->global;
|
global = wpa_s->global;
|
||||||
ifname = os_strdup(wpa_s->ifname);
|
ifname = os_strdup(wpa_s->ifname);
|
||||||
type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
|
type = wpas_p2p_if_type(wpa_s->p2p_group_interface);
|
||||||
|
eloop_cancel_timeout(run_wpas_p2p_disconnect, wpa_s, NULL);
|
||||||
wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
|
wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
|
||||||
wpa_s = global->ifaces;
|
wpa_s = global->ifaces;
|
||||||
if (wpa_s && ifname)
|
if (wpa_s && ifname)
|
||||||
|
@ -5023,6 +5055,7 @@ void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
|
||||||
int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
|
int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
|
||||||
{
|
{
|
||||||
struct wpa_global *global = wpa_s->global;
|
struct wpa_global *global = wpa_s->global;
|
||||||
|
struct wpa_supplicant *calling_wpa_s = wpa_s;
|
||||||
|
|
||||||
if (os_strcmp(ifname, "*") == 0) {
|
if (os_strcmp(ifname, "*") == 0) {
|
||||||
struct wpa_supplicant *prev;
|
struct wpa_supplicant *prev;
|
||||||
|
@ -5034,7 +5067,7 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
|
||||||
NOT_P2P_GROUP_INTERFACE ||
|
NOT_P2P_GROUP_INTERFACE ||
|
||||||
(prev->current_ssid &&
|
(prev->current_ssid &&
|
||||||
prev->current_ssid->p2p_group))
|
prev->current_ssid->p2p_group))
|
||||||
wpas_p2p_disconnect(prev);
|
wpas_p2p_disconnect_safely(prev, calling_wpa_s);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5044,7 +5077,7 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wpas_p2p_disconnect(wpa_s);
|
return wpas_p2p_disconnect_safely(wpa_s, calling_wpa_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue