From cdf3fb1f1ca969c5c14ee148aa54e5ee4e7743a7 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 6 Nov 2013 00:57:38 +0200 Subject: [PATCH] Fix removal of a BSS that has not yet been fully initialized If a secondary BSS is removed while it is waiting for the primary BSS to complete channel setup (e.g., due to HT co-ex scan, ACS, or DFS), the hostapd_data instance has not yet been initialized. Fix the BSS removal code to take this special case into account and not try to deinitialize the hostapd_data instance that has not yet been started. Signed-hostap: Jouni Malinen --- src/ap/hostapd.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 94aefe9f8..e2a1a5f51 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1818,27 +1818,32 @@ fail: static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) { - struct hostapd_data *hapd; size_t i; - if (idx > iface->num_bss || idx > iface->conf->num_bss) - return -1; - hapd = iface->bss[idx]; - wpa_printf(MSG_INFO, "Remove BSS '%s'", hapd->conf->iface); + wpa_printf(MSG_INFO, "Remove BSS '%s'", iface->conf->bss[idx]->iface); - hostapd_free_stas(hapd); - hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); - hostapd_clear_wep(hapd); - hostapd_cleanup(hapd); - hostapd_config_free_bss(hapd->conf); - os_free(hapd); + /* Remove hostapd_data only if it has already been initialized */ + if (idx < iface->num_bss) { + struct hostapd_data *hapd = iface->bss[idx]; - iface->num_bss--; - for (i = idx; i < iface->num_bss; i++) - iface->bss[i] = iface->bss[i + 1]; + hostapd_free_stas(hapd); + hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING); + hostapd_clear_wep(hapd); + hostapd_cleanup(hapd); + hostapd_config_free_bss(hapd->conf); + os_free(hapd); + + iface->num_bss--; + + for (i = idx; i < iface->num_bss; i++) + iface->bss[i] = iface->bss[i + 1]; + } else { + hostapd_config_free_bss(iface->conf->bss[idx]); + iface->conf->bss[idx] = NULL; + } iface->conf->num_bss--; - for (i = idx; i < iface->num_bss; i++) + for (i = idx; i < iface->conf->num_bss; i++) iface->conf->bss[i] = iface->conf->bss[i + 1]; return 0;