From 6e7b4c45fae6333a6ab3665f27b386e83a69264a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 26 Nov 2018 00:51:38 +0200 Subject: [PATCH] Fix hostapd config file reloading with BSS addition/removal BSS additional/removal cases were not considered at all in the previous implementation of hostapd configuration file reloading on SIGHUP. Such changes resulted in num_bss values getting out of sync in runtime data and configuration data and likely dereferencing of freed memory (e.g., when removing a BSS). Fix this by forcing a full disable/enable sequence for the interface if any BSS entry is added/removed or if an interface name changes between the old and the new configuration. Signed-off-by: Jouni Malinen --- src/ap/hostapd.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 117ee0836..aeeddf938 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -176,8 +176,27 @@ static void hostapd_clear_old(struct hostapd_iface *iface) } +static int hostapd_iface_conf_changed(struct hostapd_config *newconf, + struct hostapd_config *oldconf) +{ + size_t i; + + if (newconf->num_bss != oldconf->num_bss) + return 1; + + for (i = 0; i < newconf->num_bss; i++) { + if (os_strcmp(newconf->bss[i]->iface, + oldconf->bss[i]->iface) != 0) + return 1; + } + + return 0; +} + + int hostapd_reload_config(struct hostapd_iface *iface) { + struct hapd_interfaces *interfaces = iface->interfaces; struct hostapd_data *hapd = iface->bss[0]; struct hostapd_config *newconf, *oldconf; size_t j; @@ -200,6 +219,35 @@ int hostapd_reload_config(struct hostapd_iface *iface) hostapd_clear_old(iface); oldconf = hapd->iconf; + if (hostapd_iface_conf_changed(newconf, oldconf)) { + char *fname; + int res; + + wpa_printf(MSG_DEBUG, + "Configuration changes include interface/BSS modification - force full disable+enable sequence"); + fname = os_strdup(iface->config_fname); + if (!fname) { + hostapd_config_free(newconf); + return -1; + } + hostapd_remove_iface(interfaces, hapd->conf->iface); + iface = hostapd_init(interfaces, fname); + os_free(fname); + hostapd_config_free(newconf); + if (!iface) { + wpa_printf(MSG_ERROR, + "Failed to initialize interface on config reload"); + return -1; + } + iface->interfaces = interfaces; + interfaces->iface[interfaces->count] = iface; + interfaces->count++; + res = hostapd_enable_iface(iface); + if (res < 0) + wpa_printf(MSG_ERROR, + "Failed to enable interface on config reload"); + return res; + } iface->conf = newconf; for (j = 0; j < iface->num_bss; j++) {