Skip to content

Commit

Permalink
modem: cmux: added validation of cmux frame length
Browse files Browse the repository at this point in the history
Validates cmux frame length and drops it if its larger
than the receive buffer

Signed-off-by: Henrik Skreslet <henrik.skreslet@gmail.com>
  • Loading branch information
henr1k authored and mmahadevan108 committed Nov 7, 2024
1 parent c3466b1 commit e254a7f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
8 changes: 8 additions & 0 deletions subsys/modem/modem_cmux.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
50 changes: 50 additions & 0 deletions tests/subsys/modem/modem_cmux/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
/*************************************************************************************************/
Expand Down Expand Up @@ -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);

0 comments on commit e254a7f

Please sign in to comment.