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 <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-03-24 22:38:35 +02:00 committed by Jouni Malinen
parent 09e38c2fce
commit 4d1e38be9e
2 changed files with 27 additions and 18 deletions

View file

@ -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], &params) < 0) {
wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
acs_cleanup(iface);
os_free(params.freqs);
return -1;
}

View file

@ -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