From 4d1e38be9e833c4040243d101d34c8ded4b949e1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 24 Mar 2014 22:38:35 +0200 Subject: [PATCH] ACS: Fix number of error path issues Especially when multiple BSSes are used with ACS, number of the error paths were not cleaning up driver initialization properly. This could result in using freed memory and crashing the process if ACS failed. Signed-off-by: Jouni Malinen --- src/ap/acs.c | 3 ++- src/ap/hostapd.c | 42 +++++++++++++++++++++++++----------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/ap/acs.c b/src/ap/acs.c index 2491b78fa..b94b8a438 100644 --- a/src/ap/acs.c +++ b/src/ap/acs.c @@ -749,7 +749,7 @@ static void acs_scan_complete(struct hostapd_iface *iface) err = hostapd_drv_get_survey(iface->bss[0], 0); if (err) { wpa_printf(MSG_ERROR, "ACS: Failed to get survey data"); - acs_fail(iface); + goto fail; } if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) { @@ -801,6 +801,7 @@ static int acs_request_scan(struct hostapd_iface *iface) if (hostapd_driver_scan(iface->bss[0], ¶ms) < 0) { wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan"); acs_cleanup(iface); + os_free(params.freqs); return -1; } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 2ecaec82b..ed2226cab 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1591,6 +1591,27 @@ void hostapd_interface_deinit_free(struct hostapd_iface *iface) } +static void hostapd_deinit_driver(const struct wpa_driver_ops *driver, + void *drv_priv, + struct hostapd_iface *hapd_iface) +{ + size_t j; + + wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", + __func__, driver, drv_priv); + if (driver && driver->hapd_deinit && drv_priv) { + driver->hapd_deinit(drv_priv); + for (j = 0; j < hapd_iface->num_bss; j++) { + wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p", + __func__, (int) j, + hapd_iface->bss[j]->drv_priv); + if (hapd_iface->bss[j]->drv_priv == drv_priv) + hapd_iface->bss[j]->drv_priv = NULL; + } + } +} + + int hostapd_enable_iface(struct hostapd_iface *hapd_iface) { if (hapd_iface->bss[0]->drv_priv != NULL) { @@ -1613,17 +1634,9 @@ int hostapd_enable_iface(struct hostapd_iface *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; - wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", - __func__, driver, drv_priv); - if (driver && driver->hapd_deinit && drv_priv) { - driver->hapd_deinit(drv_priv); - hapd_iface->bss[0]->drv_priv = NULL; - } + hostapd_deinit_driver(hapd_iface->bss[0]->driver, + hapd_iface->bss[0]->drv_priv, + hapd_iface); return -1; } @@ -1676,12 +1689,7 @@ int hostapd_disable_iface(struct hostapd_iface *hapd_iface) hostapd_free_hapd_data(hapd); } - wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", - __func__, driver, drv_priv); - if (driver && driver->hapd_deinit && drv_priv) { - driver->hapd_deinit(drv_priv); - hapd_iface->bss[0]->drv_priv = NULL; - } + hostapd_deinit_driver(driver, drv_priv, hapd_iface); /* From hostapd_cleanup_iface: These were initialized in * hostapd_setup_interface and hostapd_setup_interface_complete