P2P: Fix P2P interface remuval through wpa_supplicant_remove_iface()

wpa_supplicant_remove_iface() removes the P2P management interface from
the global interfaces list before calling wpa_supplicant_deinit_iface().
When wpas_p2p_group_remove() is called from
wpa_supplicant_deinit_iface(), the P2P group created on the calling
wpa_s was not getting cleared as the calling wpa_s is not in the list of
global->ifaces. This results in the P2P management interface being
removed without disconnecting the p2p_group created on it. This could
result in an illegal access of freed memory, e.g., when a pending eloop
task wpas_p2p_reconsider_moving_go() was triggered with the leftover ctx
pointer to the removed P2P interface instance.

Fix this by disconnecting the P2P group created on interface to be
deinitialized before deinitializing the interface.

Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
This commit is contained in:
Veerendranath Jakkam 2020-09-25 18:09:00 +05:30 committed by Jouni Malinen
parent 760d10cdea
commit 57536a5678

View file

@ -5870,6 +5870,8 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
if (os_strcmp(ifname, "*") == 0) { if (os_strcmp(ifname, "*") == 0) {
struct wpa_supplicant *prev; struct wpa_supplicant *prev;
bool calling_wpa_s_group_removed = false;
wpa_s = global->ifaces; wpa_s = global->ifaces;
while (wpa_s) { while (wpa_s) {
prev = wpa_s; prev = wpa_s;
@ -5877,9 +5879,23 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
if (prev->p2p_group_interface != if (prev->p2p_group_interface !=
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_safely(prev, calling_wpa_s); wpas_p2p_disconnect_safely(prev, calling_wpa_s);
if (prev == calling_wpa_s)
calling_wpa_s_group_removed = true;
} }
}
if (!calling_wpa_s_group_removed &&
(calling_wpa_s->p2p_group_interface !=
NOT_P2P_GROUP_INTERFACE ||
(calling_wpa_s->current_ssid &&
calling_wpa_s->current_ssid->p2p_group))) {
wpa_printf(MSG_DEBUG, "Remove calling_wpa_s P2P group");
wpas_p2p_disconnect_safely(calling_wpa_s,
calling_wpa_s);
}
return 0; return 0;
} }