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)
|
||||
{
|
||||
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++) {
|
||||
|
|
Loading…
Reference in a new issue