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:
parent
09e38c2fce
commit
4d1e38be9e
2 changed files with 27 additions and 18 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue