ACS: Fix number of error path issues
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 24 Mar 2014 20:38:35 +0000 (22:38 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 25 Mar 2014 11:12:29 +0000 (13:12 +0200)
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>
src/ap/acs.c
src/ap/hostapd.c

index 2491b78..b94b8a4 100644 (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;
        }
 
index 2ecaec8..ed2226c 100644 (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