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 <j@w1.fi>
This commit is contained in:
parent
cabbaac119
commit
6e7b4c45fa
1 changed files with 48 additions and 0 deletions
|
@ -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)
|
int hostapd_reload_config(struct hostapd_iface *iface)
|
||||||
{
|
{
|
||||||
|
struct hapd_interfaces *interfaces = iface->interfaces;
|
||||||
struct hostapd_data *hapd = iface->bss[0];
|
struct hostapd_data *hapd = iface->bss[0];
|
||||||
struct hostapd_config *newconf, *oldconf;
|
struct hostapd_config *newconf, *oldconf;
|
||||||
size_t j;
|
size_t j;
|
||||||
|
@ -200,6 +219,35 @@ int hostapd_reload_config(struct hostapd_iface *iface)
|
||||||
hostapd_clear_old(iface);
|
hostapd_clear_old(iface);
|
||||||
|
|
||||||
oldconf = hapd->iconf;
|
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;
|
iface->conf = newconf;
|
||||||
|
|
||||||
for (j = 0; j < iface->num_bss; j++) {
|
for (j = 0; j < iface->num_bss; j++) {
|
||||||
|
|
Loading…
Reference in a new issue