From 57536a567821c2833ca8e64e313070054224b1a6 Mon Sep 17 00:00:00 2001 From: Veerendranath Jakkam Date: Fri, 25 Sep 2020 18:09:00 +0530 Subject: [PATCH] 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 --- wpa_supplicant/p2p_supplicant.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index e26e8051d..36fb05557 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -5870,6 +5870,8 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname) if (os_strcmp(ifname, "*") == 0) { struct wpa_supplicant *prev; + bool calling_wpa_s_group_removed = false; + wpa_s = global->ifaces; while (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 != NOT_P2P_GROUP_INTERFACE || (prev->current_ssid && - prev->current_ssid->p2p_group)) + prev->current_ssid->p2p_group)) { 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; }