From f7c478337957d4a669cce2675ba7749d7318c518 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 27 Dec 2009 21:31:13 +0200 Subject: [PATCH] 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. --- hostapd/main.c | 33 ++++++++++++++++----------------- src/ap/hostapd.c | 6 ++++++ src/ap/hostapd.h | 1 + wpa_supplicant/ap.c | 1 + 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/hostapd/main.c b/hostapd/main.c index eb0ef595c..71dfdc97d 100644 --- a/hostapd/main.c +++ b/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); diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 492c6a592..158c9b606 100644 --- a/src/ap/hostapd.c +++ b/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); diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 27ac98430..f3cbad26d 100644 --- a/src/ap/hostapd.h +++ b/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); diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 3b5488ef4..51651d596 100644 --- a/wpa_supplicant/ap.c +++ b/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; }