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.
This commit is contained in:
Jouni Malinen 2009-12-27 21:31:13 +02:00
parent f78feb6a72
commit f7c4783379
4 changed files with 24 additions and 17 deletions

View file

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

View file

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

View file

@ -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(struct hostapd_iface *iface);
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
void hostapd_interface_deinit(struct hostapd_iface *iface); 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, void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
int reassoc); int reassoc);

View file

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