Skip to content

Commit 3e3b346

Browse files
committed
Merge branch 'fix/oob_overflow' into 'master'
fix(espnow): Fix where attacker-controlled `espnow_data->size` is validated... See merge request ae_group/esp-now!153
2 parents fa4b3a8 + caf76f0 commit 3e3b346

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

src/espnow/src/espnow.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,19 @@ void espnow_recv_cb(const uint8_t *addr, const uint8_t *data, int size)
190190
rx_ctrl = &promiscuous_pkt->rx_ctrl;
191191
#endif
192192

193+
/**< Validate actual packet length before reading any header fields (CWE-125, CWE-20) */
194+
if (size < (int)sizeof(espnow_data_t)) {
195+
ESP_LOGD(TAG, "Receive cb args error: packet too short (size %d < %d)", size, (int)sizeof(espnow_data_t));
196+
return;
197+
}
198+
193199
ESP_LOG_BUFFER_HEXDUMP(TAG, data, size, ESP_LOG_DEBUG);
194200
ESP_LOGD(TAG, "[%s, %d], " MACSTR ", rssi: %d, size: %d, total: %d - %d, type: %d, addr: %02x, g_msg_magic_cache_next: %d",
195201
__func__, __LINE__, MAC2STR(addr), rx_ctrl->rssi, size, espnow_data->size, sizeof(espnow_data_t), espnow_data->type, addr[5], g_msg_magic_cache_next);
196202

197203
/**< Filter ESP-NOW packets not generated by this project */
198204
if (espnow_data->version != ESPNOW_VERSION || (espnow_data->type >= ESPNOW_DATA_TYPE_MAX)
199-
|| size != espnow_data->size + sizeof(espnow_data_t)
205+
|| size != (int)(sizeof(espnow_data_t) + espnow_data->size)
200206
|| ESPNOW_ADDR_IS_SELF(espnow_data->src_addr)) {
201207
ESP_LOGD(TAG, "Receive cb args error, recv_addr: "MACSTR", src_addr: " MACSTR ", data: %p, size: %d",
202208
MAC2STR(addr), MAC2STR(espnow_data->src_addr), data, size);
@@ -309,6 +315,11 @@ void espnow_recv_cb(const uint8_t *addr, const uint8_t *data, int size)
309315

310316
goto EXIT;
311317
} else if (espnow_data->type == ESPNOW_DATA_TYPE_GROUP) {
318+
if (size < (int)(sizeof(espnow_data_t) + sizeof(espnow_group_info_t))) {
319+
ESP_LOGD(TAG, "[%s, %d] GROUP packet too short for group_info (size %d)", __func__, __LINE__, size);
320+
return;
321+
}
322+
312323
espnow_group_info_t *group_info = (espnow_group_info_t *) espnow_data->payload;
313324
bool set_group_flag = false;
314325

@@ -320,6 +331,11 @@ void espnow_recv_cb(const uint8_t *addr, const uint8_t *data, int size)
320331
if (group_info->addrs_num == 1 && ESPNOW_ADDR_IS_BROADCAST(group_info->addrs_list[0])) {
321332
set_group_flag = true;
322333
} else {
334+
if (size < (int)(sizeof(espnow_data_t) + sizeof(espnow_group_info_t) + group_info->addrs_num * ESPNOW_ADDR_LEN)) {
335+
ESP_LOGD(TAG, "[%s, %d] GROUP packet too short for addrs_list (size %d, addrs_num %d)", __func__, __LINE__, size, group_info->addrs_num);
336+
return;
337+
}
338+
323339
if (espnow_data->size < (sizeof(espnow_group_info_t) + group_info->addrs_num * ESPNOW_ADDR_LEN)) {
324340
ESP_LOGD(TAG, "[%s, %d] The size %d of the data must match with total size for addrs_num: %d", __func__, __LINE__, espnow_data->size, group_info->addrs_num);
325341
return;

0 commit comments

Comments
 (0)