From 71cdf6b62454ab0c48e70aae5ff168d1d1d57466 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 2 Nov 2013 19:49:01 +0200 Subject: [PATCH] hostapd: Fix ENABLE failure to not remove interface Previously, ENABLE command ended up freeing the hostapd_iface context on initialization failures, but did not even remove the interface from the list of available interfaces. This resulted in use of freed memory with any following operation on the same interface. In addition, removing the interface on initialization failure does not seem like the best approach. Fix both of these issues by leaving the interface instance in memory, but in disabled state so that the configuration can be fixed and ENABLE used again to enable the interface or REMOVE used to remove the interface. Signed-hostap: Jouni Malinen --- src/ap/ap_drv_ops.c | 3 ++- src/ap/hostapd.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c index 5e6b15ec9..9753960d0 100644 --- a/src/ap/ap_drv_ops.c +++ b/src/ap/ap_drv_ops.c @@ -430,7 +430,8 @@ int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type, int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type, const char *ifname) { - if (hapd->driver == NULL || hapd->driver->if_remove == NULL) + if (hapd->driver == NULL || hapd->drv_priv == NULL || + hapd->driver->if_remove == NULL) return -1; return hapd->driver->if_remove(hapd->drv_priv, type, ifname); } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 8ae753cbf..faeb56556 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1364,11 +1364,22 @@ int hostapd_enable_iface(struct hostapd_iface *hapd_iface) if (hapd_iface->interfaces == NULL || hapd_iface->interfaces->driver_init == NULL || - hapd_iface->interfaces->driver_init(hapd_iface) || - hostapd_setup_interface(hapd_iface)) { - hostapd_interface_deinit_free(hapd_iface); + hapd_iface->interfaces->driver_init(hapd_iface)) + return -1; + + if (hostapd_setup_interface(hapd_iface)) { + const struct wpa_driver_ops *driver; + void *drv_priv; + + driver = hapd_iface->bss[0]->driver; + drv_priv = hapd_iface->bss[0]->drv_priv; + if (driver && driver->hapd_deinit && drv_priv) { + driver->hapd_deinit(drv_priv); + hapd_iface->bss[0]->drv_priv = NULL; + } return -1; } + return 0; }