Browse Source

Split hostapd_interface_deinit() into deinit and free parts

This allows the driver interface to be deinitialized before
struct hostapd_data instance gets freed. This needs to be done so
that the driver wrapper does not maintain a context pointer to
freed memory.
Jouni Malinen 15 years ago
parent
commit
f7c4783379
4 changed files with 24 additions and 17 deletions
  1. 16 17
      hostapd/main.c
  2. 6 0
      src/ap/hostapd.c
  3. 1 0
      src/ap/hostapd.h
  4. 1 0
      wpa_supplicant/ap.c

+ 16 - 17
hostapd/main.c

@@ -275,6 +275,19 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 }
 
 
+static void hostapd_interface_deinit_free(struct hostapd_iface *iface)
+{
+	const struct wpa_driver_ops *driver;
+	void *drv_priv;
+	driver = iface->bss[0]->driver;
+	drv_priv = iface->bss[0]->drv_priv;
+	hostapd_interface_deinit(iface);
+	if (driver && driver->hapd_deinit)
+		driver->hapd_deinit(drv_priv);
+	hostapd_interface_free(iface);
+}
+
+
 static struct hostapd_iface *
 hostapd_interface_init(struct hapd_interfaces *interfaces,
 		       const char *config_fname, int debug)
@@ -295,13 +308,7 @@ hostapd_interface_init(struct hapd_interfaces *interfaces,
 
 	if (hostapd_driver_init(iface) ||
 	    hostapd_setup_interface(iface)) {
-		const struct wpa_driver_ops *driver;
-		void *drv_priv;
-		driver = iface->bss[0]->driver;
-		drv_priv = iface->bss[0]->drv_priv;
-		hostapd_interface_deinit(iface);
-		if (driver && driver->hapd_deinit)
-			driver->hapd_deinit(drv_priv);
+		hostapd_interface_deinit_free(iface);
 		return NULL;
 	}
 
@@ -542,16 +549,8 @@ int main(int argc, char *argv[])
 
  out:
 	/* Deinitialize all interfaces */
-	for (i = 0; i < interfaces.count; i++) {
-		struct hostapd_iface *iface = interfaces.iface[i];
-		const struct wpa_driver_ops *driver;
-		void *drv_priv;
-		driver = iface->bss[0]->driver;
-		drv_priv = iface->bss[0]->drv_priv;
-		hostapd_interface_deinit(iface);
-		if (driver && driver->hapd_deinit)
-			driver->hapd_deinit(drv_priv);
-	}
+	for (i = 0; i < interfaces.count; i++)
+		hostapd_interface_deinit_free(interfaces.iface[i]);
 	os_free(interfaces.iface);
 
 	hostapd_global_deinit(pid_file);

+ 6 - 0
src/ap/hostapd.c

@@ -822,6 +822,12 @@ void hostapd_interface_deinit(struct hostapd_iface *iface)
 		hostapd_flush_old_stations(hapd);
 		hostapd_cleanup(hapd);
 	}
+}
+
+
+void hostapd_interface_free(struct hostapd_iface *iface)
+{
+	size_t j;
 	for (j = 0; j < iface->num_bss; j++)
 		os_free(iface->bss[j]);
 	hostapd_cleanup_iface(iface);

+ 1 - 0
src/ap/hostapd.h

@@ -243,6 +243,7 @@ hostapd_alloc_bss_data(struct hostapd_iface *hapd_iface,
 int hostapd_setup_interface(struct hostapd_iface *iface);
 int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
 void hostapd_interface_deinit(struct hostapd_iface *iface);
+void hostapd_interface_free(struct hostapd_iface *iface);
 void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
 			   int reassoc);
 

+ 1 - 0
wpa_supplicant/ap.c

@@ -223,6 +223,7 @@ void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
 		return;
 
 	hostapd_interface_deinit(wpa_s->ap_iface);
+	hostapd_interface_free(wpa_s->ap_iface);
 	wpa_s->ap_iface = NULL;
 }