mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(esp_netif): stop L2TAP IREC walk on non-advancing records
This commit is contained in:
@@ -1008,6 +1008,28 @@ TEST_CASE("esp32 l2tap - time stamping", "[ethernet]")
|
||||
TEST_ASSERT_EQUAL(exp_n, n);
|
||||
TEST_ASSERT_EQUAL(exp_sequence_id, ((test_eth_ptp_msg_t *)in_buffer)->ptp_msg.ptp_hdr.sequence_id);
|
||||
|
||||
ESP_LOGI(TAG, "Verify read IREC walk terminates when truncated record overlays a 0/0 timestamp");
|
||||
ts_info->type = L2TAP_IREC_TIME_STAMP;
|
||||
ts_info->len = L2TAP_IREC_LEN(sizeof(struct timespec));
|
||||
test_ptp_msg.ptp_msg.ptp_hdr.sequence_id++;
|
||||
exp_sequence_id++;
|
||||
ptp_msg_ext_buff.buff = &test_ptp_msg;
|
||||
ptp_msg_ext_buff.buff_len = sizeof(test_ptp_msg);
|
||||
n = write(eth_tap_fd, &ptp_msg_ext_buff, 0);
|
||||
TEST_ASSERT_EQUAL(sizeof(test_ptp_msg), n);
|
||||
// 0/0 is an invalid timestamp. Reusing this IREC buffer with a truncated len makes
|
||||
// L2TAP_IREC_NEXT land on tv_nsec==0 (a zero-length pseudo-header) and must not hang.
|
||||
struct timespec *stale_ts = (struct timespec *)ts_info->data;
|
||||
stale_ts->tv_sec = 0;
|
||||
stale_ts->tv_nsec = 0;
|
||||
ts_info->type = 0xFF;
|
||||
ts_info->len = L2TAP_IREC_LEN(1);
|
||||
ptp_msg_ext_buff.buff = in_buffer;
|
||||
ptp_msg_ext_buff.buff_len = IN_BUFFER_SIZE;
|
||||
n = read(eth_tap_fd, &ptp_msg_ext_buff, 0);
|
||||
exp_n = sizeof(test_ptp_msg) < 60 ? 60 : sizeof(test_ptp_msg);
|
||||
TEST_ASSERT_EQUAL(exp_n, n);
|
||||
TEST_ASSERT_EQUAL(exp_sequence_id, ((test_eth_ptp_msg_t *)in_buffer)->ptp_msg.ptp_hdr.sequence_id);
|
||||
|
||||
ESP_LOGI(TAG, "Verify response to invalid record len for read (first we need write correctly)");
|
||||
ts_info->type = L2TAP_IREC_TIME_STAMP;
|
||||
|
||||
@@ -183,11 +183,22 @@ static esp_err_t pop_rx_queue(l2tap_context_t *l2tap_socket, void *buff, size_t
|
||||
if (l2tap_socket->flags & L2TAP_FLAG_TS) {
|
||||
// find the record allocated for the time stamp info
|
||||
l2tap_irec_hdr_t *info_rec = L2TAP_IREC_FIRST(ext_buff);
|
||||
while(info_rec != NULL) {
|
||||
while (info_rec != NULL) {
|
||||
/* rec->len is the NEXT stride. A truncated/invalid record (or leftover
|
||||
* payload interpreted as a header) can have len < header size, */
|
||||
if (info_rec->len < sizeof(l2tap_irec_hdr_t)) {
|
||||
info_rec = NULL;
|
||||
break;
|
||||
}
|
||||
if (info_rec->type == L2TAP_IREC_TIME_STAMP) {
|
||||
break;
|
||||
}
|
||||
info_rec = L2TAP_IREC_NEXT(ext_buff, info_rec);
|
||||
l2tap_irec_hdr_t *info_rec_next = L2TAP_IREC_NEXT(ext_buff, info_rec);
|
||||
if (info_rec_next == NULL || (uint8_t *)info_rec_next <= (uint8_t *)info_rec) {
|
||||
info_rec = NULL;
|
||||
break;
|
||||
}
|
||||
info_rec = info_rec_next;
|
||||
}
|
||||
if (info_rec != NULL) {
|
||||
// check if there is enough space to store TS
|
||||
|
||||
Reference in New Issue
Block a user