diff --git a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c index 6157b5c234..56f1c9cd7c 100644 --- a/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c +++ b/components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c @@ -832,6 +832,7 @@ static void periodic_scan_roam(struct timeval *now) roaming_app_get_ap_info(&g_roaming_app.current_bss.ap); ESP_LOGD(ROAMING_TAG, "Connected AP's RSSI=%d", g_roaming_app.current_bss.ap.rssi); if (g_roaming_app.current_bss.ap.rssi > g_roaming_app.config.scan_rssi_threshold) { + ESP_LOGD(ROAMING_TAG, "Not going for scan, Scan RSSI threshold=%d", g_roaming_app.config.scan_rssi_threshold); return; } diff --git a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c index 751b59149d..040013d65e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c +++ b/components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c @@ -255,31 +255,6 @@ cleanup: return res; } -int crypto_bignum_to_string(const struct crypto_bignum *a, - u8 *buf, size_t buflen, size_t padlen) -{ - int num_bytes, offset; - size_t outlen; - - if (padlen > buflen) { - return -1; - } - - num_bytes = mbedtls_mpi_size((mbedtls_mpi *) a); - - if (padlen > (size_t) num_bytes) { - offset = padlen - num_bytes; - } else { - offset = 0; - } - - os_memset(buf, 0, offset); - mbedtls_mpi_write_string((mbedtls_mpi *) a, 16, (char *)(buf + offset), - mbedtls_mpi_size((mbedtls_mpi *)a), &outlen); - - return outlen; -} - int crypto_bignum_addmod(const struct crypto_bignum *a, const struct crypto_bignum *b, const struct crypto_bignum *c, diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_common.c b/components/wpa_supplicant/esp_supplicant/src/esp_common.c index 7671daa0e0..6361434763 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_common.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_common.c @@ -169,6 +169,9 @@ static int handle_assoc_frame(u8 *frame, size_t len, u8 *sender, int8_t rssi, u8 channel) { if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK || gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_SAE) { + if (len < 6) { /* Cap info + status code */ + return -1; + } if (gWpaSm.ft_protocol) { if (wpa_ft_validate_reassoc_resp(&gWpaSm, frame + 6, len - 6, sender)) { wpa_sm_set_ft_params(&gWpaSm, NULL, 0); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c index ee7a833aa2..9d2088d50e 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_dpp.c @@ -385,6 +385,10 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param) return ESP_ERR_INVALID_ARG; } + if (rx_param->vendor_data_len < 2) { + wpa_printf(MSG_INFO, "DPP: Too short vendor specific data"); + return ESP_FAIL; + } size_t len = rx_param->vendor_data_len - 2; buf = rx_param->action_frm->u.public_action.v.pa_vendor_spec.vendor_data; @@ -519,28 +523,38 @@ static esp_err_t gas_query_resp_rx(struct action_rx_param *rx_param) { struct dpp_authentication *auth = s_dpp_ctx.dpp_auth; uint8_t *pos = rx_param->action_frm->u.public_action.v.pa_gas_resp.data; - uint8_t *resp = &pos[10]; + uint8_t *resp = &pos[10]; /* first byte of DPP attributes */ + size_t vendor_len = rx_param->vendor_data_len; int i, res; - if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && - WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) { + /* Basic structural checks on the Advertisement Protocol payload */ + if (!(pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 && + WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth)) { + wpa_hexdump(MSG_INFO, "DPP: Failed, Configuration Response adv_proto", pos, 8); + return ESP_OK; + } - eloop_cancel_timeout(gas_query_timeout, NULL, auth); - if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) { - wpa_printf(MSG_INFO, "DPP: Configuration attempt failed"); + /* DPP attribute length = vendor_data_len - 2, caller validated vendor_data_len + * (we skip the 2-byte length field and pass only the attributes). */ + size_t dpp_data_len = vendor_len - 2; + + eloop_cancel_timeout(gas_query_timeout, NULL, auth); + + if (dpp_conf_resp_rx(auth, resp, dpp_data_len) < 0) { + wpa_printf(MSG_INFO, "DPP: Configuration attempt failed"); + goto fail; + } + + for (i = 0; i < auth->num_conf_obj; i++) { + res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]); + if (res < 0) { + wpa_printf(MSG_INFO, "DPP: Configuration parsing failed"); goto fail; } - - for (i = 0; i < auth->num_conf_obj; i++) { - res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]); - if (res < 0) { - wpa_printf(MSG_INFO, "DPP: Configuration parsing failed"); - goto fail; - } - } } return ESP_OK; + fail: return ESP_FAIL; } @@ -821,11 +835,17 @@ static char *esp_dpp_parse_chan_list(const char *chan_list) } char *uri_ptr = uri_channels; + size_t current_offset = 0; // Use an offset to track current position params->num_chan = 0; /* Append " chan=" at the beginning of the URI */ - strcpy(uri_ptr, " chan="); - uri_ptr += strlen(" chan="); + int written = os_snprintf(uri_ptr + current_offset, max_uri_len - current_offset, " chan="); + if (written < 0 || written >= max_uri_len - current_offset) { // Check for error or truncation + wpa_printf(MSG_ERROR, "DPP: URI buffer too small for initial string"); + os_free(uri_channels); + return NULL; + } + current_offset += written; while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) { int channel = 0; @@ -860,16 +880,23 @@ static char *esp_dpp_parse_chan_list(const char *chan_list) /* Add the valid channel to the list */ params->chan_list[params->num_chan++] = channel; - /* Check if there's space left in uri_channels buffer */ - size_t remaining_space = max_uri_len - (uri_ptr - uri_channels); - if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator - wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer"); + // Calculate space needed for current channel string (e.g., "81/1,") + int needed_for_channel = os_snprintf(NULL, 0, "%d/%d,", oper_class, channel); + + if (current_offset + needed_for_channel + 1 > max_uri_len) { // +1 for null terminator + wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer for channel %d", channel); os_free(uri_channels); return NULL; } /* Append the operating class and channel to the URI */ - uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel); + written = os_snprintf(uri_ptr + current_offset, max_uri_len - current_offset, "%d/%d,", oper_class, channel); + if (written < 0 || written >= max_uri_len - current_offset) { // Check for error or truncation + wpa_printf(MSG_ERROR, "DPP: Error writing channel %d to URI buffer", channel); + os_free(uri_channels); + return NULL; + } + current_offset += written; /* Skip any delimiters (comma or space) */ while (*chan_list == ',' || *chan_list == ' ') { @@ -884,8 +911,8 @@ static char *esp_dpp_parse_chan_list(const char *chan_list) } /* Replace the last comma with a space if there was content added */ - if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') { - *(uri_ptr - 1) = ' '; + if (current_offset > strlen(" chan=") && uri_ptr[current_offset - 1] == ',') { + uri_ptr[current_offset - 1] = ' '; } return uri_channels; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c index 007a3e928b..2a072da7cf 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_hostap.c @@ -214,7 +214,8 @@ void *hostap_init(void) } #endif /* CONFIG_SAE */ - os_memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal())); + os_snprintf(hapd->conf->ssid.wpa_passphrase, WIFI_PASSWORD_LEN_MAX, + "%s", esp_wifi_ap_get_prof_password_internal()); hapd->conf->ssid.wpa_passphrase[WIFI_PASSWORD_LEN_MAX - 1] = '\0'; hapd->conf->max_num_sta = esp_wifi_ap_get_max_sta_conn(); auth_conf->transition_disable = esp_wifi_ap_get_transition_disable_internal(); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c index 153fc63334..eb66633038 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c @@ -343,8 +343,16 @@ static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status) wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token container header"); return ESP_FAIL; } + if (len < 5) { + wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token length"); + return ESP_FAIL; + } g_sae_token = wpabuf_alloc_copy(buf + 5, len - 5); } else { + if (len < 2) { + wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token length"); + return ESP_FAIL; + } g_sae_token = wpabuf_alloc_copy(buf + 2, len - 2); } return ESP_OK; diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 7a5f9c2b8b..ccdfb6d455 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -389,8 +389,8 @@ static int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *f identifier = sm->current_identifier; if (*buf == NULL) { - if (0 == (flag & WPS_MSG_FLAG_LEN) || tot_len < frag_len) { - wpa_printf(MSG_ERROR, "WPS: %s: Invalid fragment flag: 0x%02x", __FUNCTION__, flag); + if (frag_len < 0 || tot_len < frag_len) { + wpa_printf(MSG_ERROR, "WPS: Invalid first fragment length"); return ESP_FAIL; } @@ -405,9 +405,17 @@ static int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *f if (flag & WPS_MSG_FLAG_LEN) { wpa_printf(MSG_ERROR, "WPS: %s: Invalid fragment flag: 0x%02x", __func__, flag); + wpabuf_free(*buf); + *buf = NULL; return ESP_FAIL; } + if (frag_len < 0 || wpabuf_len(*buf) + frag_len > tot_len) { + wpa_printf(MSG_ERROR, "WPS: Invalid subsequent fragment length"); + wpabuf_free(*buf); + *buf = NULL; + return ESP_FAIL; + } wpabuf_put_data(*buf, frag_data, frag_len); if (flag & WPS_MSG_FLAG_MORE) { @@ -445,6 +453,10 @@ static int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) return ESP_FAIL; } + if (len < (int)(sizeof(struct eap_expand) + 1)) { + wpa_printf(MSG_ERROR, "WPS: Truncated EAP-Expanded header"); + return ESP_FAIL; + } expd = (struct eap_expand *) ubuf; wpa_printf(MSG_DEBUG, "WPS: Processing WSC message (len=%d, total_len=%d)", len, tlen); @@ -463,7 +475,11 @@ static int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) flag = *(u8 *)(ubuf + sizeof(struct eap_expand)); if (flag & WPS_MSG_FLAG_LEN) { - tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2;//two bytes total length + if (len < (int)(sizeof(struct eap_expand) + 1 + 2)) { + wpa_printf(MSG_ERROR, "WPS: Missing total length field"); + return ESP_FAIL; + } + tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2; // includes 2-byte total length frag_len = len - (sizeof(struct eap_expand) + 1 + 2); be_tot_len = *(u16 *)(ubuf + sizeof(struct eap_expand) + 1); tlen = ((be_tot_len & 0xff) << 8) | ((be_tot_len >> 8) & 0xff); @@ -473,6 +489,15 @@ static int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res) tlen = frag_len; } + if (frag_len < 0 || tlen < 0 || ((flag & WPS_MSG_FLAG_LEN) && tlen < frag_len)) { + wpa_printf(MSG_ERROR, "WPS: Invalid fragment sizes"); + if (wps_buf) { + wpabuf_free(wps_buf); + wps_buf = NULL; + } + return ESP_FAIL; + } + if (tlen > 50000) { wpa_printf(MSG_ERROR, "WPS: Invalid EAP-WSC message length"); return ESP_FAIL; diff --git a/components/wpa_supplicant/src/crypto/crypto.h b/components/wpa_supplicant/src/crypto/crypto.h index 0164b63be0..7db0c1d484 100644 --- a/components/wpa_supplicant/src/crypto/crypto.h +++ b/components/wpa_supplicant/src/crypto/crypto.h @@ -1153,17 +1153,6 @@ void crypto_free_buffer(unsigned char *buf); */ int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_data, int *key_len); -/** - * crypto_bignum_to_string: get big number in ascii format - * @a: big number - * @buf: buffer in which number will written to - * @buflen: buffer length - * @padlen: padding length - * Return : 0 if success - */ -int crypto_bignum_to_string(const struct crypto_bignum *a, - u8 *buf, size_t buflen, size_t padlen); - struct crypto_ecdh; void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);