From: Jouni Malinen Date: Mon, 5 Jan 2015 19:57:15 +0000 (+0200) Subject: Fix hostapd initialization error path on allocation failure X-Git-Tag: hostap_2_4~524 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=28016592680365ec509cd306bc95d03f76057de2;p=thirdparty%2Fhostap.git Fix hostapd initialization error path on allocation failure If hostapd_alloc_bss_data() failed to allocate the struct hostapd_data instance, dynamic interface addition path ended up trying to dereference freed memory due to incorrect cleanup steps. Fix this by decrementing the interface count when the newly added interface is removed. In addition, make the setup more robust by clearing all changes within hostapd_data_alloc() if any of the allocations fails. Signed-off-by: Jouni Malinen --- diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 2103747e7..04a0b69db 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1872,33 +1872,37 @@ hostapd_config_alloc(struct hapd_interfaces *interfaces, const char *ifname, } -static struct hostapd_iface * hostapd_data_alloc( - struct hapd_interfaces *interfaces, struct hostapd_config *conf) +static int hostapd_data_alloc(struct hostapd_iface *hapd_iface, + struct hostapd_config *conf) { size_t i; - struct hostapd_iface *hapd_iface = - interfaces->iface[interfaces->count - 1]; struct hostapd_data *hapd; - hapd_iface->conf = conf; - hapd_iface->num_bss = conf->num_bss; - hapd_iface->bss = os_calloc(conf->num_bss, sizeof(struct hostapd_data *)); if (hapd_iface->bss == NULL) - return NULL; + return -1; for (i = 0; i < conf->num_bss; i++) { hapd = hapd_iface->bss[i] = hostapd_alloc_bss_data(hapd_iface, conf, conf->bss[i]); - if (hapd == NULL) - return NULL; + if (hapd == NULL) { + while (i > 0) { + i--; + os_free(hapd_iface->bss[i]); + hapd_iface->bss[i] = NULL; + } + os_free(hapd_iface->bss); + hapd_iface->bss = NULL; + return -1; + } hapd->msg_ctx = hapd; } - hapd_iface->interfaces = interfaces; + hapd_iface->conf = conf; + hapd_iface->num_bss = conf->num_bss; - return hapd_iface; + return 0; } @@ -1945,13 +1949,10 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) } if (new_iface) { - if (interfaces->driver_init(hapd_iface)) { - interfaces->count--; + if (interfaces->driver_init(hapd_iface)) goto fail; - } if (hostapd_setup_interface(hapd_iface)) { - interfaces->count--; hostapd_deinit_driver( hapd_iface->bss[0]->driver, hapd_iface->bss[0]->drv_priv, @@ -2005,6 +2006,7 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) "for interface", __func__); goto fail; } + new_iface = hapd_iface; if (conf_file && interfaces->config_read_cb) { conf = interfaces->config_read_cb(conf_file); @@ -2019,8 +2021,7 @@ int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf) goto fail; } - hapd_iface = hostapd_data_alloc(interfaces, conf); - if (hapd_iface == NULL) { + if (hostapd_data_alloc(hapd_iface, conf) < 0) { wpa_printf(MSG_ERROR, "%s: Failed to allocate memory " "for hostapd", __func__); goto fail; @@ -2056,6 +2057,10 @@ fail: os_free(hapd_iface->bss); hapd_iface->bss = NULL; } + if (new_iface) { + interfaces->count--; + interfaces->iface[interfaces->count] = NULL; + } hostapd_cleanup_iface(hapd_iface); } return -1; @@ -2076,6 +2081,7 @@ static int hostapd_remove_bss(struct hostapd_iface *iface, unsigned int idx) wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)", __func__, hapd, hapd->conf->iface); hostapd_config_free_bss(hapd->conf); + hapd->conf = NULL; os_free(hapd); iface->num_bss--;