Cumulative patch from commit 801e117376e13d5b3c50f1627b93a949529fdf99
801e117 Fix validation of RSN EAPOL-Key version for GCMP with PMF
3d4d234 FT: Fix GTK rekeying after FT protocol
d3d0483 nl80211: Work around error case prints for nl_recvmsgs on Android
8a387a2 P2P NFC: Fix use of freed memory
df48efc Fix external radio work stopping to not read freed memory
13c3303 SAE: Fix memory leak in random number generation
d92bdf9 hostapd: Make sure hapd->drv_priv gets cleared on driver deinit
438e133 hostapd: Use helper function to avoid duplicate deinit calls
ac1a224 hostapd: Clean up if interface setup fails
81c4fca hostapd: Reset hapd->interface_add properly
3fbd036 hostapd: Prevent double interface disabling from segfaulting
ea39367 nl80211: Fix wpa_driver_nl80211_if_add() failure paths
b77aeae Interworking: Re-trigger scan if no connect attempt is done
b523973 RADIUS client: Trigger failover more quickly if socket is not valid
09844c0 RADIUS client: Do not flush pending messages if server did not change
5d67bf1 hostapd: Fix configuration of multiple RADIUS servers with SET
70d4084 RADIUS client: Fix socket close/re-open on server change
d045cc8 RADIUS client: Fix crash issue in radius_client_timer()
c1fb75a RADIUS client: Handle ENETUNREACH similarly to other failure cases
9ed4076 RADIUS client: Do not try to send message without socket
cc0b7cb hostapd_cli: Fix segmentation fault with interface command
114153b P2P: Debug print channel lists for invitation processing
4eb3b76 OpenSSL: Fix OCSP certificate debug print to use wpa_printf
f6fb192 HS 2.0R2: Fix subscr_remediation_method for RADIUS server
74879f3 Remove extra newline from a debug print
Change-Id: I82d4f00501fabb8b325e4461178b45e7b2c0178e
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index b7e118c..ed73301 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -277,10 +277,21 @@
authsrv_deinit(hapd);
- if (hapd->interface_added &&
- hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
- wpa_printf(MSG_WARNING, "Failed to remove BSS interface %s",
- hapd->conf->iface);
+ if (hapd->interface_added) {
+ hapd->interface_added = 0;
+ if (hostapd_if_remove(hapd, WPA_IF_AP_BSS, hapd->conf->iface)) {
+ wpa_printf(MSG_WARNING,
+ "Failed to remove BSS interface %s",
+ hapd->conf->iface);
+ hapd->interface_added = 1;
+ } else {
+ /*
+ * Since this was a dynamically added interface, the
+ * driver wrapper may have removed its internal instance
+ * and hapd->drv_priv is not valid anymore.
+ */
+ hapd->drv_priv = NULL;
+ }
}
os_free(hapd->probereq_cb);
@@ -433,6 +444,14 @@
}
+static void hostapd_bss_deinit_no_free(struct hostapd_data *hapd)
+{
+ hostapd_free_stas(hapd);
+ hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
+ hostapd_clear_wep(hapd);
+}
+
+
/**
* hostapd_validate_bssid_configuration - Validate BSSID configuration
* @iface: Pointer to interface data
@@ -1226,8 +1245,14 @@
hapd = iface->bss[j];
if (j)
os_memcpy(hapd->own_addr, prev_addr, ETH_ALEN);
- if (hostapd_setup_bss(hapd, j == 0))
+ if (hostapd_setup_bss(hapd, j == 0)) {
+ do {
+ hapd = iface->bss[j];
+ hostapd_bss_deinit_no_free(hapd);
+ hostapd_free_hapd_data(hapd);
+ } while (j-- > 0);
goto fail;
+ }
if (hostapd_mac_comp_empty(hapd->conf->bssid) == 0)
prev_addr = hapd->own_addr;
}
@@ -1346,9 +1371,7 @@
{
wpa_printf(MSG_DEBUG, "%s: deinit bss %s", __func__,
hapd->conf->iface);
- hostapd_free_stas(hapd);
- hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
- hostapd_clear_wep(hapd);
+ hostapd_bss_deinit_no_free(hapd);
hostapd_cleanup(hapd);
}
@@ -1601,8 +1624,10 @@
hostapd_interface_deinit(iface);
wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
__func__, driver, drv_priv);
- if (driver && driver->hapd_deinit && drv_priv)
+ if (driver && driver->hapd_deinit && drv_priv) {
driver->hapd_deinit(drv_priv);
+ iface->bss[0]->drv_priv = NULL;
+ }
hostapd_interface_free(iface);
}
@@ -1630,6 +1655,8 @@
int hostapd_enable_iface(struct hostapd_iface *hapd_iface)
{
+ size_t j;
+
if (hapd_iface->bss[0]->drv_priv != NULL) {
wpa_printf(MSG_ERROR, "Interface %s already enabled",
hapd_iface->conf->bss[0]->iface);
@@ -1639,6 +1666,8 @@
wpa_printf(MSG_DEBUG, "Enable interface %s",
hapd_iface->conf->bss[0]->iface);
+ for (j = 0; j < hapd_iface->num_bss; j++)
+ hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
wpa_printf(MSG_INFO, "Invalid configuration - cannot enable");
return -1;
@@ -1667,7 +1696,7 @@
wpa_printf(MSG_DEBUG, "Reload interface %s",
hapd_iface->conf->bss[0]->iface);
for (j = 0; j < hapd_iface->num_bss; j++)
- hostapd_set_security_params(hapd_iface->conf->bss[j]);
+ hostapd_set_security_params(hapd_iface->conf->bss[j], 1);
if (hostapd_config_check(hapd_iface->conf, 1) < 0) {
wpa_printf(MSG_ERROR, "Updated configuration is invalid");
return -1;
@@ -1688,6 +1717,13 @@
if (hapd_iface == NULL)
return -1;
+
+ if (hapd_iface->bss[0]->drv_priv == NULL) {
+ wpa_printf(MSG_INFO, "Interface %s already disabled",
+ hapd_iface->conf->bss[0]->iface);
+ return -1;
+ }
+
wpa_msg(hapd_iface->bss[0]->msg_ctx, MSG_INFO, AP_EVENT_DISABLED);
driver = hapd_iface->bss[0]->driver;
drv_priv = hapd_iface->bss[0]->drv_priv;
@@ -1699,9 +1735,7 @@
/* same as hostapd_interface_deinit without deinitializing ctrl-iface */
for (j = 0; j < hapd_iface->num_bss; j++) {
struct hostapd_data *hapd = hapd_iface->bss[j];
- hostapd_free_stas(hapd);
- hostapd_flush_old_stations(hapd, WLAN_REASON_DEAUTH_LEAVING);
- hostapd_clear_wep(hapd);
+ hostapd_bss_deinit_no_free(hapd);
hostapd_free_hapd_data(hapd);
}