mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'bugfix/invalid_memory_access_supplicant_v6.0' into 'release/v6.0'
fix(esp_wifi): Fix some invalid memory access (v6.0) See merge request espressif/esp-idf!44273
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user