WPS: Clear WPS data on init failure
It was possible for hapd->wps_beacon_ie and hapd->wps_probe_resp_ie to be set if WPS initialization in hostapd failed after having set these parameters (e.g., during UPnP configuration). In addition, many of the other WPS configuration parameters that were allocated during the first part of the initialization were not properly freed on error paths. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
d2a4005b3b
commit
20ff2642e1
1 changed files with 38 additions and 27 deletions
|
@ -40,6 +40,7 @@ static int hostapd_wps_probe_req_rx(void *ctx, const u8 *addr, const u8 *da,
|
|||
const u8 *ie, size_t ie_len,
|
||||
int ssi_signal);
|
||||
static void hostapd_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
|
||||
static void hostapd_wps_nfc_clear(struct wps_context *wps);
|
||||
|
||||
|
||||
struct wps_for_each_data {
|
||||
|
@ -897,7 +898,7 @@ static int hostapd_wps_rf_band_cb(void *ctx)
|
|||
}
|
||||
|
||||
|
||||
static void hostapd_wps_clear_ies(struct hostapd_data *hapd)
|
||||
static void hostapd_wps_clear_ies(struct hostapd_data *hapd, int deinit_only)
|
||||
{
|
||||
wpabuf_free(hapd->wps_beacon_ie);
|
||||
hapd->wps_beacon_ie = NULL;
|
||||
|
@ -905,6 +906,9 @@ static void hostapd_wps_clear_ies(struct hostapd_data *hapd)
|
|||
wpabuf_free(hapd->wps_probe_resp_ie);
|
||||
hapd->wps_probe_resp_ie = NULL;
|
||||
|
||||
if (deinit_only)
|
||||
return;
|
||||
|
||||
hostapd_set_ap_wps_ie(hapd);
|
||||
}
|
||||
|
||||
|
@ -987,6 +991,21 @@ static int hostapd_wps_set_vendor_ext(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
static void hostapd_free_wps(struct wps_context *wps)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_WPS_VENDOR_EXTENSIONS; i++)
|
||||
wpabuf_free(wps->dev.vendor_ext[i]);
|
||||
wps_device_data_free(&wps->dev);
|
||||
os_free(wps->network_key);
|
||||
hostapd_wps_nfc_clear(wps);
|
||||
wpabuf_free(wps->dh_pubkey);
|
||||
wpabuf_free(wps->dh_privkey);
|
||||
os_free(wps);
|
||||
}
|
||||
|
||||
|
||||
int hostapd_init_wps(struct hostapd_data *hapd,
|
||||
struct hostapd_bss_config *conf)
|
||||
{
|
||||
|
@ -994,7 +1013,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
|||
struct wps_registrar_config cfg;
|
||||
|
||||
if (conf->wps_state == 0) {
|
||||
hostapd_wps_clear_ies(hapd);
|
||||
hostapd_wps_clear_ies(hapd, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1062,10 +1081,8 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
|||
os_memcpy(wps->dev.pri_dev_type, hapd->conf->device_type,
|
||||
WPS_DEV_TYPE_LEN);
|
||||
|
||||
if (hostapd_wps_set_vendor_ext(hapd, wps) < 0) {
|
||||
os_free(wps);
|
||||
return -1;
|
||||
}
|
||||
if (hostapd_wps_set_vendor_ext(hapd, wps) < 0)
|
||||
goto fail;
|
||||
|
||||
wps->dev.os_version = WPA_GET_BE32(hapd->conf->os_version);
|
||||
|
||||
|
@ -1125,19 +1142,15 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
|||
wps->network_key_len = os_strlen(conf->ssid.wpa_passphrase);
|
||||
} else if (conf->ssid.wpa_psk) {
|
||||
wps->network_key = os_malloc(2 * PMK_LEN + 1);
|
||||
if (wps->network_key == NULL) {
|
||||
os_free(wps);
|
||||
return -1;
|
||||
}
|
||||
if (wps->network_key == NULL)
|
||||
goto fail;
|
||||
wpa_snprintf_hex((char *) wps->network_key, 2 * PMK_LEN + 1,
|
||||
conf->ssid.wpa_psk->psk, PMK_LEN);
|
||||
wps->network_key_len = 2 * PMK_LEN;
|
||||
} else if (conf->ssid.wep.keys_set && conf->ssid.wep.key[0]) {
|
||||
wps->network_key = os_malloc(conf->ssid.wep.len[0]);
|
||||
if (wps->network_key == NULL) {
|
||||
os_free(wps);
|
||||
return -1;
|
||||
}
|
||||
if (wps->network_key == NULL)
|
||||
goto fail;
|
||||
os_memcpy(wps->network_key, conf->ssid.wep.key[0],
|
||||
conf->ssid.wep.len[0]);
|
||||
wps->network_key_len = conf->ssid.wep.len[0];
|
||||
|
@ -1183,9 +1196,7 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
|||
wps->registrar = wps_registrar_init(wps, &cfg);
|
||||
if (wps->registrar == NULL) {
|
||||
wpa_printf(MSG_ERROR, "Failed to initialize WPS Registrar");
|
||||
os_free(wps->network_key);
|
||||
os_free(wps);
|
||||
return -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_WPS_UPNP
|
||||
|
@ -1201,6 +1212,10 @@ int hostapd_init_wps(struct hostapd_data *hapd,
|
|||
hapd->wps = wps;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
hostapd_free_wps(wps);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1215,8 +1230,7 @@ int hostapd_init_wps_complete(struct hostapd_data *hapd)
|
|||
if (hostapd_wps_upnp_init(hapd, wps) < 0) {
|
||||
wpa_printf(MSG_ERROR, "Failed to initialize WPS UPnP");
|
||||
wps_registrar_deinit(wps->registrar);
|
||||
os_free(wps->network_key);
|
||||
os_free(wps);
|
||||
hostapd_free_wps(wps);
|
||||
hapd->wps = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
@ -1246,21 +1260,18 @@ void hostapd_deinit_wps(struct hostapd_data *hapd)
|
|||
eloop_cancel_timeout(hostapd_wps_reenable_ap_pin, hapd, NULL);
|
||||
eloop_cancel_timeout(hostapd_wps_ap_pin_timeout, hapd, NULL);
|
||||
eloop_cancel_timeout(wps_reload_config, hapd->iface, NULL);
|
||||
if (hapd->wps == NULL)
|
||||
if (hapd->wps == NULL) {
|
||||
hostapd_wps_clear_ies(hapd, 1);
|
||||
return;
|
||||
}
|
||||
#ifdef CONFIG_WPS_UPNP
|
||||
hostapd_wps_upnp_deinit(hapd);
|
||||
#endif /* CONFIG_WPS_UPNP */
|
||||
wps_registrar_deinit(hapd->wps->registrar);
|
||||
os_free(hapd->wps->network_key);
|
||||
wps_device_data_free(&hapd->wps->dev);
|
||||
wpabuf_free(hapd->wps->dh_pubkey);
|
||||
wpabuf_free(hapd->wps->dh_privkey);
|
||||
wps_free_pending_msgs(hapd->wps->upnp_msgs);
|
||||
hostapd_wps_nfc_clear(hapd->wps);
|
||||
os_free(hapd->wps);
|
||||
hostapd_free_wps(hapd->wps);
|
||||
hapd->wps = NULL;
|
||||
hostapd_wps_clear_ies(hapd);
|
||||
hostapd_wps_clear_ies(hapd, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue