Skip to content

Commit 6f6766f

Browse files
committed
Merge branch 'bugfix/invalid_memory_access_supplicant_v5.3' into 'release/v5.3'
fix(esp_wifi): Fix some invalid memory access (v5.3) See merge request espressif/esp-idf!44276
2 parents e5b9047 + e25dd27 commit 6f6766f

File tree

8 files changed

+92
-62
lines changed

8 files changed

+92
-62
lines changed

components/esp_wifi/wifi_apps/roaming_app/src/roaming_app.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ static void periodic_scan_roam(struct timeval *now)
696696
roaming_app_get_ap_info(&g_roaming_app.current_bss.ap);
697697
ESP_LOGD(ROAMING_TAG, "Connected AP's RSSI=%d", g_roaming_app.current_bss.ap.rssi);
698698
if (g_roaming_app.current_bss.ap.rssi > g_roaming_app.config.scan_rssi_threshold) {
699+
ESP_LOGD(ROAMING_TAG, "Not going for scan, Scan RSSI threshold=%d", g_roaming_app.config.scan_rssi_threshold);
699700
return;
700701
}
701702

components/wpa_supplicant/esp_supplicant/src/crypto/crypto_mbedtls-bignum.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -252,31 +252,6 @@ int crypto_bignum_legendre(const struct crypto_bignum *a,
252252
return res;
253253
}
254254

255-
int crypto_bignum_to_string(const struct crypto_bignum *a,
256-
u8 *buf, size_t buflen, size_t padlen)
257-
{
258-
int num_bytes, offset;
259-
size_t outlen;
260-
261-
if (padlen > buflen) {
262-
return -1;
263-
}
264-
265-
num_bytes = mbedtls_mpi_size((mbedtls_mpi *) a);
266-
267-
if (padlen > (size_t) num_bytes) {
268-
offset = padlen - num_bytes;
269-
} else {
270-
offset = 0;
271-
}
272-
273-
os_memset(buf, 0, offset);
274-
mbedtls_mpi_write_string((mbedtls_mpi *) a, 16, (char *)(buf + offset),
275-
mbedtls_mpi_size((mbedtls_mpi *)a), &outlen);
276-
277-
return outlen;
278-
}
279-
280255
int crypto_bignum_addmod(const struct crypto_bignum *a,
281256
const struct crypto_bignum *b,
282257
const struct crypto_bignum *c,

components/wpa_supplicant/esp_supplicant/src/esp_common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ static int handle_assoc_frame(u8 *frame, size_t len,
167167
u8 *sender, int8_t rssi, u8 channel)
168168
{
169169
if (gWpaSm.key_mgmt == WPA_KEY_MGMT_FT_PSK) {
170+
if (len < 6) { /* Cap info + status code */
171+
return -1;
172+
}
170173
if (gWpaSm.ft_protocol) {
171174
if (wpa_ft_validate_reassoc_resp(&gWpaSm, frame + 6, len - 6, sender)) {
172175
wpa_sm_set_ft_params(&gWpaSm, NULL, 0);

components/wpa_supplicant/esp_supplicant/src/esp_dpp.c

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,10 @@ static esp_err_t esp_dpp_rx_peer_disc_resp(struct action_rx_param *rx_param)
302302
return ESP_ERR_INVALID_ARG;
303303
}
304304

305+
if (rx_param->vendor_data_len < 2) {
306+
wpa_printf(MSG_INFO, "DPP: Too short vendor specific data");
307+
return ESP_FAIL;
308+
}
305309
size_t len = rx_param->vendor_data_len - 2;
306310

307311
buf = rx_param->action_frm->u.public_action.v.pa_vendor_spec.vendor_data;
@@ -437,25 +441,36 @@ static void gas_query_resp_rx(struct action_rx_param *rx_param)
437441
{
438442
struct dpp_authentication *auth = s_dpp_ctx.dpp_auth;
439443
uint8_t *pos = rx_param->action_frm->u.public_action.v.pa_gas_resp.data;
440-
uint8_t *resp = &pos[10];
444+
uint8_t *resp = &pos[10]; /* first byte of DPP attributes */
445+
size_t vendor_len = rx_param->vendor_data_len;
441446
int i, res;
442447

443-
if (pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 &&
444-
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth) {
445-
if (dpp_conf_resp_rx(auth, resp, rx_param->vendor_data_len - 2) < 0) {
446-
wpa_printf(MSG_DEBUG, "DPP: Configuration attempt failed");
447-
goto fail;
448-
}
448+
/* Basic structural checks on the Advertisement Protocol payload */
449+
if (!(pos[1] == WLAN_EID_VENDOR_SPECIFIC && pos[2] == 5 &&
450+
WPA_GET_BE24(&pos[3]) == OUI_WFA && pos[6] == 0x1a && pos[7] == 1 && auth)) {
451+
wpa_hexdump(MSG_INFO, "DPP: Failed, Configuration Response adv_proto", pos, 8);
452+
return;
453+
}
449454

450-
for (i = 0; i < auth->num_conf_obj; i++) {
451-
res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]);
452-
if (res < 0) {
453-
goto fail;
454-
}
455+
/* DPP attribute length = vendor_data_len - 2, caller validated vendor_data_len
456+
* (we skip the 2-byte length field and pass only the attributes). */
457+
size_t dpp_data_len = vendor_len - 2;
458+
459+
if (dpp_conf_resp_rx(auth, resp, dpp_data_len) < 0) {
460+
wpa_printf(MSG_INFO, "DPP: Configuration attempt failed");
461+
goto fail;
462+
}
463+
464+
for (i = 0; i < auth->num_conf_obj; i++) {
465+
res = esp_dpp_handle_config_obj(auth, &auth->conf_obj[i]);
466+
if (res < 0) {
467+
wpa_printf(MSG_INFO, "DPP: Configuration parsing failed");
468+
goto fail;
455469
}
456470
}
457471

458472
return;
473+
459474
fail:
460475
esp_dpp_call_cb(ESP_SUPP_DPP_FAIL, (void *)ESP_ERR_DPP_FAILURE);
461476
}
@@ -694,11 +709,17 @@ static char *esp_dpp_parse_chan_list(const char *chan_list)
694709
}
695710

696711
char *uri_ptr = uri_channels;
712+
size_t current_offset = 0; // Use an offset to track current position
697713
params->num_chan = 0;
698714

699715
/* Append " chan=" at the beginning of the URI */
700-
strcpy(uri_ptr, " chan=");
701-
uri_ptr += strlen(" chan=");
716+
int written = os_snprintf(uri_ptr + current_offset, max_uri_len - current_offset, " chan=");
717+
if (written < 0 || written >= max_uri_len - current_offset) { // Check for error or truncation
718+
wpa_printf(MSG_ERROR, "DPP: URI buffer too small for initial string");
719+
os_free(uri_channels);
720+
return NULL;
721+
}
722+
current_offset += written;
702723

703724
while (*chan_list && params->num_chan < ESP_DPP_MAX_CHAN_COUNT) {
704725
int channel = 0;
@@ -733,16 +754,23 @@ static char *esp_dpp_parse_chan_list(const char *chan_list)
733754
/* Add the valid channel to the list */
734755
params->chan_list[params->num_chan++] = channel;
735756

736-
/* Check if there's space left in uri_channels buffer */
737-
size_t remaining_space = max_uri_len - (uri_ptr - uri_channels);
738-
if (remaining_space <= 8) { // Oper class + "/" + channel + "," + null terminator
739-
wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer");
757+
// Calculate space needed for current channel string (e.g., "81/1,")
758+
int needed_for_channel = os_snprintf(NULL, 0, "%d/%d,", oper_class, channel);
759+
760+
if (current_offset + needed_for_channel + 1 > max_uri_len) { // +1 for null terminator
761+
wpa_printf(MSG_ERROR, "DPP: Not enough space in URI buffer for channel %d", channel);
740762
os_free(uri_channels);
741763
return NULL;
742764
}
743765

744766
/* Append the operating class and channel to the URI */
745-
uri_ptr += sprintf(uri_ptr, "%d/%d,", oper_class, channel);
767+
written = os_snprintf(uri_ptr + current_offset, max_uri_len - current_offset, "%d/%d,", oper_class, channel);
768+
if (written < 0 || written >= max_uri_len - current_offset) { // Check for error or truncation
769+
wpa_printf(MSG_ERROR, "DPP: Error writing channel %d to URI buffer", channel);
770+
os_free(uri_channels);
771+
return NULL;
772+
}
773+
current_offset += written;
746774

747775
/* Skip any delimiters (comma or space) */
748776
while (*chan_list == ',' || *chan_list == ' ') {
@@ -757,8 +785,8 @@ static char *esp_dpp_parse_chan_list(const char *chan_list)
757785
}
758786

759787
/* Replace the last comma with a space if there was content added */
760-
if (uri_ptr > uri_channels && *(uri_ptr - 1) == ',') {
761-
*(uri_ptr - 1) = ' ';
788+
if (current_offset > strlen(" chan=") && uri_ptr[current_offset - 1] == ',') {
789+
uri_ptr[current_offset - 1] = ' ';
762790
}
763791

764792
return uri_channels;

components/wpa_supplicant/esp_supplicant/src/esp_hostap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,8 @@ void *hostap_init(void)
193193
}
194194
#endif /* CONFIG_SAE */
195195

196-
os_memcpy(hapd->conf->ssid.wpa_passphrase, esp_wifi_ap_get_prof_password_internal(), strlen((char *)esp_wifi_ap_get_prof_password_internal()));
196+
os_snprintf(hapd->conf->ssid.wpa_passphrase, WIFI_PASSWORD_LEN_MAX,
197+
"%s", esp_wifi_ap_get_prof_password_internal());
197198
hapd->conf->ssid.wpa_passphrase[WIFI_PASSWORD_LEN_MAX - 1] = '\0';
198199
hapd->conf->max_num_sta = esp_wifi_ap_get_max_sta_conn();
199200
auth_conf->transition_disable = esp_wifi_ap_get_transition_disable_internal();

components/wpa_supplicant/esp_supplicant/src/esp_wpa3.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,16 @@ static int wpa3_parse_sae_commit(u8 *buf, u32 len, u16 status)
319319
wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token container header");
320320
return ESP_FAIL;
321321
}
322+
if (len < 5) {
323+
wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token length");
324+
return ESP_FAIL;
325+
}
322326
g_sae_token = wpabuf_alloc_copy(buf + 5, len - 5);
323327
} else {
328+
if (len < 2) {
329+
wpa_printf(MSG_ERROR, "Invalid SAE anti-clogging token length");
330+
return ESP_FAIL;
331+
}
324332
g_sae_token = wpabuf_alloc_copy(buf + 2, len - 2);
325333
}
326334
return ESP_OK;

components/wpa_supplicant/esp_supplicant/src/esp_wps.c

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,8 @@ int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *frag_dat
569569
}
570570

571571
if (*buf == NULL) {
572-
if (0 == (flag & WPS_MSG_FLAG_LEN) || tot_len < frag_len) {
573-
wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag);
572+
if (frag_len < 0 || tot_len < frag_len) {
573+
wpa_printf(MSG_ERROR, "WPS: Invalid first fragment length");
574574
return ESP_FAIL;
575575
}
576576

@@ -584,10 +584,18 @@ int wps_enrollee_process_msg_frag(struct wpabuf **buf, int tot_len, u8 *frag_dat
584584
}
585585

586586
if (flag & WPS_MSG_FLAG_LEN) {
587-
wpa_printf(MSG_ERROR, "fun:%s. line:%d, flag error:%02x", __FUNCTION__, __LINE__, flag);
587+
wpa_printf(MSG_ERROR, "WPS: %s: Invalid fragment flag: 0x%02x", __func__, flag);
588+
wpabuf_free(*buf);
589+
*buf = NULL;
588590
return ESP_FAIL;
589591
}
590592

593+
if (frag_len < 0 || wpabuf_len(*buf) + frag_len > tot_len) {
594+
wpa_printf(MSG_ERROR, "WPS: Invalid subsequent fragment length");
595+
wpabuf_free(*buf);
596+
*buf = NULL;
597+
return ESP_FAIL;
598+
}
591599
wpabuf_put_data(*buf, frag_data, frag_len);
592600

593601
if (flag & WPS_MSG_FLAG_MORE) {
@@ -612,6 +620,10 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
612620
return ESP_FAIL;
613621
}
614622

623+
if (len < (int)(sizeof(struct eap_expand) + 1)) {
624+
wpa_printf(MSG_ERROR, "WPS: Truncated EAP-Expanded header");
625+
return ESP_FAIL;
626+
}
615627
expd = (struct eap_expand *) ubuf;
616628
wpa_printf(MSG_DEBUG, "wps process mX req: len %d, tlen %d", len, tlen);
617629

@@ -631,7 +643,11 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
631643

632644
flag = *(u8 *)(ubuf + sizeof(struct eap_expand));
633645
if (flag & WPS_MSG_FLAG_LEN) {
634-
tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2;//two bytes total length
646+
if (len < (int)(sizeof(struct eap_expand) + 1 + 2)) {
647+
wpa_printf(MSG_ERROR, "WPS: Missing total length field");
648+
return ESP_FAIL;
649+
}
650+
tbuf = ubuf + sizeof(struct eap_expand) + 1 + 2; // includes 2-byte total length
635651
frag_len = len - (sizeof(struct eap_expand) + 1 + 2);
636652
be_tot_len = *(u16 *)(ubuf + sizeof(struct eap_expand) + 1);
637653
tlen = ((be_tot_len & 0xff) << 8) | ((be_tot_len >> 8) & 0xff);
@@ -641,6 +657,15 @@ int wps_process_wps_mX_req(u8 *ubuf, int len, enum wps_process_res *res)
641657
tlen = frag_len;
642658
}
643659

660+
if (frag_len < 0 || tlen < 0 || ((flag & WPS_MSG_FLAG_LEN) && tlen < frag_len)) {
661+
wpa_printf(MSG_ERROR, "WPS: Invalid fragment sizes");
662+
if (wps_buf) {
663+
wpabuf_free(wps_buf);
664+
wps_buf = NULL;
665+
}
666+
return ESP_FAIL;
667+
}
668+
644669
if (tlen > 50000) {
645670
wpa_printf(MSG_ERROR, "EAP-WSC: Invalid Message Length");
646671
return ESP_FAIL;

components/wpa_supplicant/src/crypto/crypto.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,17 +1135,6 @@ void crypto_free_buffer(unsigned char *buf);
11351135
*/
11361136
int crypto_ec_get_priv_key_der(struct crypto_ec_key *key, unsigned char **key_data, int *key_len);
11371137

1138-
/**
1139-
* crypto_bignum_to_string: get big number in ascii format
1140-
* @a: big number
1141-
* @buf: buffer in which number will written to
1142-
* @buflen: buffer length
1143-
* @padlen: padding length
1144-
* Return : 0 if success
1145-
*/
1146-
int crypto_bignum_to_string(const struct crypto_bignum *a,
1147-
u8 *buf, size_t buflen, size_t padlen);
1148-
11491138
struct crypto_ecdh;
11501139

11511140
void crypto_ecdh_deinit(struct crypto_ecdh *ecdh);

0 commit comments

Comments
 (0)