From 1772d348ea3f6748596c1bd69387457f53d996c4 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 1 Mar 2015 21:50:34 +0200 Subject: [PATCH] P2P: Fix interface deinit for failed group interface initialization wpa_supplicant_deinit_iface() ends up removing all P2P groups if the removed interface is the parent interface. This is correct behavior in general, but this resulted in issues in the new group interface initialization error path since wpa_s->parent was not assigned before hitting this check. Fix this by assigning wpa_s->parent as part of wpa_supplicant_add_iface(). Signed-off-by: Jouni Malinen --- wpa_supplicant/ctrl_iface.c | 2 +- wpa_supplicant/dbus/dbus_new_handlers.c | 2 +- wpa_supplicant/dbus/dbus_old_handlers.c | 2 +- wpa_supplicant/main.c | 2 +- wpa_supplicant/main_none.c | 2 +- wpa_supplicant/main_winmain.c | 2 +- wpa_supplicant/main_winsvc.c | 2 +- wpa_supplicant/mesh.c | 3 +-- wpa_supplicant/p2p_supplicant.c | 6 ++---- wpa_supplicant/wpa_supplicant.c | 11 +++++++---- wpa_supplicant/wpa_supplicant_i.h | 3 ++- 11 files changed, 19 insertions(+), 18 deletions(-) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 7c230dcab..b4aefb65e 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -8548,7 +8548,7 @@ static int wpa_supplicant_global_iface_add(struct wpa_global *global, if (wpa_supplicant_get_iface(global, iface.ifname)) return -1; - return wpa_supplicant_add_iface(global, &iface) ? 0 : -1; + return wpa_supplicant_add_iface(global, &iface, NULL) ? 0 : -1; } diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index e7c2dd886..f2e62ca96 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -599,7 +599,7 @@ DBusMessage * wpas_dbus_handler_create_interface(DBusMessage *message, iface.confname = confname; iface.bridge_ifname = bridge_ifname; /* Otherwise, have wpa_supplicant attach to it. */ - wpa_s = wpa_supplicant_add_iface(global, &iface); + wpa_s = wpa_supplicant_add_iface(global, &iface, NULL); if (wpa_s) { const char *path = wpa_s->dbus_new_path; diff --git a/wpa_supplicant/dbus/dbus_old_handlers.c b/wpa_supplicant/dbus/dbus_old_handlers.c index 955ea782f..773ee8b49 100644 --- a/wpa_supplicant/dbus/dbus_old_handlers.c +++ b/wpa_supplicant/dbus/dbus_old_handlers.c @@ -165,7 +165,7 @@ DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, iface.confname = confname; iface.bridge_ifname = bridge_ifname; /* Otherwise, have wpa_supplicant attach to it. */ - wpa_s = wpa_supplicant_add_iface(global, &iface); + wpa_s = wpa_supplicant_add_iface(global, &iface, NULL); if (wpa_s) { const char *path = wpa_s->dbus_path; diff --git a/wpa_supplicant/main.c b/wpa_supplicant/main.c index 13e976949..22827479c 100644 --- a/wpa_supplicant/main.c +++ b/wpa_supplicant/main.c @@ -322,7 +322,7 @@ int main(int argc, char *argv[]) exitcode = -1; break; } - wpa_s = wpa_supplicant_add_iface(global, &ifaces[i]); + wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL); if (wpa_s == NULL) { exitcode = -1; break; diff --git a/wpa_supplicant/main_none.c b/wpa_supplicant/main_none.c index 010c30a30..4d3caf2a4 100644 --- a/wpa_supplicant/main_none.c +++ b/wpa_supplicant/main_none.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) memset(&iface, 0, sizeof(iface)); /* TODO: set interface parameters */ - if (wpa_supplicant_add_iface(global, &iface) == NULL) + if (wpa_supplicant_add_iface(global, &iface, NULL) == NULL) exitcode = -1; if (exitcode == 0) diff --git a/wpa_supplicant/main_winmain.c b/wpa_supplicant/main_winmain.c index 93a68f17b..e1dded0c3 100644 --- a/wpa_supplicant/main_winmain.c +++ b/wpa_supplicant/main_winmain.c @@ -61,7 +61,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, exitcode = -1; break; } - if (wpa_supplicant_add_iface(global, &ifaces[i]) == NULL) + if (wpa_supplicant_add_iface(global, &ifaces[i], NULL) == NULL) exitcode = -1; } diff --git a/wpa_supplicant/main_winsvc.c b/wpa_supplicant/main_winsvc.c index 0b7d5ce06..9950aa99a 100644 --- a/wpa_supplicant/main_winsvc.c +++ b/wpa_supplicant/main_winsvc.c @@ -119,7 +119,7 @@ static int read_interface(struct wpa_global *global, HKEY _hk, RegCloseKey(hk); - if (wpa_supplicant_add_iface(global, &iface) == NULL) { + if (wpa_supplicant_add_iface(global, &iface, NULL) == NULL) { if (skip_on_error) wpa_printf(MSG_DEBUG, "Skipped interface '%s' due to " "initialization failure", iface.ifname); diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index 32506b677..cf3676c22 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -527,7 +527,7 @@ int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname, iface.driver_param = wpa_s->conf->driver_param; iface.ctrl_interface = wpa_s->conf->ctrl_interface; - mesh_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface); + mesh_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s); if (!mesh_wpa_s) { wpa_printf(MSG_ERROR, "mesh: Failed to create new wpa_supplicant interface"); @@ -535,6 +535,5 @@ int wpas_mesh_add_interface(struct wpa_supplicant *wpa_s, char *ifname, return -1; } mesh_wpa_s->mesh_if_created = 1; - mesh_wpa_s->parent = wpa_s; return 0; } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 6ffe59588..9c7c867ae 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1990,14 +1990,13 @@ wpas_p2p_init_group_interface(struct wpa_supplicant *wpa_s, int go) else iface.ctrl_interface = wpa_s->conf->ctrl_interface; iface.driver_param = wpa_s->conf->driver_param; - group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface); + group_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s); if (group_wpa_s == NULL) { wpa_printf(MSG_ERROR, "P2P: Failed to create new " "wpa_supplicant interface"); return NULL; } wpa_s->pending_interface_name[0] = '\0'; - group_wpa_s->parent = wpa_s; group_wpa_s->p2p_group_interface = go ? P2P_GROUP_INTERFACE_GO : P2P_GROUP_INTERFACE_CLIENT; wpa_s->global->p2p_group_formation = group_wpa_s; @@ -4669,12 +4668,11 @@ int wpas_p2p_add_p2pdev_interface(struct wpa_supplicant *wpa_s, } iface.conf_p2p_dev = NULL; - p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface); + p2pdev_wpa_s = wpa_supplicant_add_iface(wpa_s->global, &iface, wpa_s); if (!p2pdev_wpa_s) { wpa_printf(MSG_DEBUG, "P2P: Failed to add P2P Device interface"); return -1; } - p2pdev_wpa_s->parent = wpa_s; wpa_s->p2p_dev = p2pdev_wpa_s; wpa_s->pending_interface_name[0] = '\0'; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 15f856935..5848202b1 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3230,7 +3230,8 @@ static int wpa_supplicant_daemon(const char *pid_file) } -static struct wpa_supplicant * wpa_supplicant_alloc(void) +static struct wpa_supplicant * +wpa_supplicant_alloc(struct wpa_supplicant *parent) { struct wpa_supplicant *wpa_s; @@ -3240,7 +3241,7 @@ static struct wpa_supplicant * wpa_supplicant_alloc(void) wpa_s->scan_req = INITIAL_SCAN_REQ; wpa_s->scan_interval = 5; wpa_s->new_connection = 1; - wpa_s->parent = wpa_s; + wpa_s->parent = parent ? parent : wpa_s; wpa_s->sched_scanning = 0; return wpa_s; @@ -4294,6 +4295,7 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, * wpa_supplicant_add_iface - Add a new network interface * @global: Pointer to global data from wpa_supplicant_init() * @iface: Interface configuration options + * @parent: Parent interface or %NULL to assign new interface as parent * Returns: Pointer to the created interface or %NULL on failure * * This function is used to add new network interfaces for %wpa_supplicant. @@ -4303,7 +4305,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, * e.g., when a hotplug network adapter is inserted. */ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, - struct wpa_interface *iface) + struct wpa_interface *iface, + struct wpa_supplicant *parent) { struct wpa_supplicant *wpa_s; struct wpa_interface t_iface; @@ -4312,7 +4315,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, if (global == NULL || iface == NULL) return NULL; - wpa_s = wpa_supplicant_alloc(); + wpa_s = wpa_supplicant_alloc(parent); if (wpa_s == NULL) return NULL; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 0c0ee84a5..26ff216b0 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1035,7 +1035,8 @@ void free_hw_features(struct wpa_supplicant *wpa_s); void wpa_show_license(void); struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global, - struct wpa_interface *iface); + struct wpa_interface *iface, + struct wpa_supplicant *parent); int wpa_supplicant_remove_iface(struct wpa_global *global, struct wpa_supplicant *wpa_s, int terminate);