]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Fix hostapd config file reloading with BSS addition/removal
authorJouni Malinen <j@w1.fi>
Sun, 25 Nov 2018 22:51:38 +0000 (00:51 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 25 Nov 2018 22:51:38 +0000 (00:51 +0200)
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 <j@w1.fi>
src/ap/hostapd.c

index 117ee08363a876be8f891e18e8ea1871defbd1a4..aeeddf9389684d6546dd55f1bddeea972b8b1aa8 100644 (file)
@@ -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++) {