modem: cmux: added validation of cmux frame length

Validates cmux frame length and drops it if its larger
than the receive buffer

Signed-off-by: Henrik Skreslet <henrik.skreslet@gmail.com>
This commit is contained in:
Henrik Skreslet 2024-10-31 08:46:00 +01:00 committed by Mahesh Mahadevan
commit e254a7f3c8
2 changed files with 58 additions and 0 deletions

View file

@ -816,6 +816,14 @@ static void modem_cmux_process_received_byte(struct modem_cmux *cmux, uint8_t by
/* Get last 8 bits of data length */
cmux->frame.data_len |= ((uint16_t)byte) << 7;
if (cmux->frame.data_len > cmux->receive_buf_size) {
LOG_ERR("Indicated frame data length %u exceeds receive buffer size %u",
cmux->frame.data_len, cmux->receive_buf_size);
cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_DROP;
break;
}
/* Await data */
cmux->receive_state = MODEM_CMUX_RECEIVE_STATE_DATA;
break;

View file

@ -148,6 +148,14 @@ static uint8_t cmux_frame_dlci2_at_newline[] = {0xF9, 0x0B, 0xEF, 0x05, 0x0D, 0x
static uint8_t cmux_frame_data_dlci2_at_newline[] = {0x0D, 0x0A};
/*************************************************************************************************/
/* DLCI2 AT CMUX error frames */
/*************************************************************************************************/
static uint8_t cmux_frame_dlci2_at_cgdcont_invalid_length[] = {
0xF9, 0x0B, 0xEF, 0xFE, 0x41, 0x54, 0x2B, 0x43, 0x47, 0x44, 0x43, 0x4F, 0x4E,
0x54, 0x3D, 0x31, 0x2C, 0x22, 0x49, 0x50, 0x22, 0x2C, 0x22, 0x74, 0x72, 0x61,
0x63, 0x6B, 0x75, 0x6E, 0x69, 0x74, 0x2E, 0x6D, 0x32, 0x6D, 0x22, 0x23, 0xF9};
/*************************************************************************************************/
/* DLCI1 AT CMUX frames */
/*************************************************************************************************/
@ -814,4 +822,46 @@ ZTEST(modem_cmux, test_modem_cmux_prevent_work_while_released)
zassert_ok(modem_pipe_open(dlci2_pipe, K_SECONDS(10)));
}
ZTEST(modem_cmux, test_modem_drop_frames_with_invalid_length)
{
int ret;
uint32_t events;
modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont_invalid_length,
sizeof(cmux_frame_dlci2_at_cgdcont_invalid_length));
k_msleep(100);
events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
zassert_false(events & EVENT_CMUX_DLCI2_RECEIVE_READY,
"Receive event should not have been received for DLCI2 pipe");
modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_cgdcont,
sizeof(cmux_frame_dlci2_at_cgdcont));
modem_backend_mock_put(&bus_mock, cmux_frame_dlci2_at_newline,
sizeof(cmux_frame_dlci2_at_newline));
k_msleep(100);
events = k_event_test(&cmux_event, EVENT_CMUX_DLCI2_RECEIVE_READY);
zassert_equal(events, EVENT_CMUX_DLCI2_RECEIVE_READY,
"Receive ready event not received for DLCI2 pipe");
ret = modem_pipe_receive(dlci2_pipe, buffer2, sizeof(buffer2));
zassert_true(ret == (sizeof(cmux_frame_data_dlci2_at_cgdcont) +
sizeof(cmux_frame_data_dlci2_at_newline)),
"Incorrect number of bytes received");
zassert_true(memcmp(buffer2, cmux_frame_data_dlci2_at_cgdcont,
sizeof(cmux_frame_data_dlci2_at_cgdcont)) == 0,
"Incorrect data received");
zassert_true(memcmp(&buffer2[sizeof(cmux_frame_data_dlci2_at_cgdcont)],
cmux_frame_data_dlci2_at_newline,
sizeof(cmux_frame_data_dlci2_at_newline)) == 0,
"Incorrect data received");
}
ZTEST_SUITE(modem_cmux, NULL, test_modem_cmux_setup, test_modem_cmux_before, NULL, NULL);