rfcomm: avoid out of bounds read, fix #336

This commit is contained in:
Matthias Ringwald 2021-02-23 15:59:39 +01:00
parent 1431ce2787
commit 11d526b3ab

View File

@ -1198,6 +1198,8 @@ static int rfcomm_multiplexer_l2cap_packet_handler(uint16_t channel, uint8_t *pa
uint16_t l2cap_cid = multiplexer->l2cap_cid; uint16_t l2cap_cid = multiplexer->l2cap_cid;
if (size < 3) return 0;
// but only care for multiplexer control channel // but only care for multiplexer control channel
uint8_t frame_dlci = packet[0] >> 2; uint8_t frame_dlci = packet[0] >> 2;
if (frame_dlci) return 0; if (frame_dlci) return 0;
@ -1239,6 +1241,8 @@ static int rfcomm_multiplexer_l2cap_packet_handler(uint16_t channel, uint8_t *pa
return 1; return 1;
case BT_RFCOMM_UIH: case BT_RFCOMM_UIH:
if (payload_offset >= size) return 0;
if (packet[payload_offset] == BT_RFCOMM_CLD_CMD){ if (packet[payload_offset] == BT_RFCOMM_CLD_CMD){
// Multiplexer close down (CLD) -> close mutliplexer // Multiplexer close down (CLD) -> close mutliplexer
log_info("Received Multiplexer close down command"); log_info("Received Multiplexer close down command");
@ -1267,11 +1271,13 @@ static int rfcomm_multiplexer_l2cap_packet_handler(uint16_t channel, uint8_t *pa
return 1; return 1;
case BT_RFCOMM_TEST_CMD: { case BT_RFCOMM_TEST_CMD: {
if ((payload_offset + 1) >= size) return 0; // (1)
log_info("Received test command"); log_info("Received test command");
int len = packet[payload_offset+1] >> 1; // length < 125 int len = packet[payload_offset+1] >> 1; // length < 125
if (len > RFCOMM_TEST_DATA_MAX_LEN){ if (len > RFCOMM_TEST_DATA_MAX_LEN){
len = RFCOMM_TEST_DATA_MAX_LEN; len = RFCOMM_TEST_DATA_MAX_LEN;
} }
// from (1) => (size - 1 - payload_offset) > 0
len = btstack_min(len, size - 1 - payload_offset); // avoid information leak len = btstack_min(len, size - 1 - payload_offset); // avoid information leak
multiplexer->test_data_len = len; multiplexer->test_data_len = len;
(void)memcpy(multiplexer->test_data, (void)memcpy(multiplexer->test_data,
@ -1731,7 +1737,7 @@ static void rfcomm_packet_handler(uint8_t packet_type, uint16_t channel, uint8_t
if (handled) return; if (handled) return;
// - channel over open mutliplexer // - channel over open multiplexer
rfcomm_multiplexer_t * multiplexer = rfcomm_multiplexer_for_l2cap_cid(channel); rfcomm_multiplexer_t * multiplexer = rfcomm_multiplexer_for_l2cap_cid(channel);
if ( (multiplexer == NULL) || (multiplexer->state != RFCOMM_MULTIPLEXER_OPEN)) return; if ( (multiplexer == NULL) || (multiplexer->state != RFCOMM_MULTIPLEXER_OPEN)) return;