From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Sagar Verma Date: Sun, 12 Jun 2022 00:05:07 +0530 Subject: [PATCH] AVRC: Validating msg size before accessing fields This change adds buffer length validation during the parsing of AVRCP browse commands. Change-Id: I3a6c7a9ea2323a04ce5c5368eabfa940a8152cba --- stack/avrc/avrc_pars_tg.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/stack/avrc/avrc_pars_tg.cc b/stack/avrc/avrc_pars_tg.cc index 7042f4da7..38c0ca385 100644 --- a/stack/avrc/avrc_pars_tg.cc +++ b/stack/avrc/avrc_pars_tg.cc @@ -407,6 +407,12 @@ tAVRC_STS AVRC_Ctrl_ParsCommand(tAVRC_MSG* p_msg, tAVRC_COMMAND* p_result) { return status; } +#define RETURN_STATUS_IF_FALSE(_status_, _b_, _msg_, ...) \ + if (!(_b_)) { \ + AVRC_TRACE_DEBUG(_msg_, ##__VA_ARGS__); \ + return _status_; \ + } + /******************************************************************************* * * Function avrc_pars_browsing_cmd @@ -425,6 +431,7 @@ static tAVRC_STS avrc_pars_browsing_cmd(tAVRC_MSG_BROWSE* p_msg, tAVRC_STS status = AVRC_STS_NO_ERROR; uint8_t* p = p_msg->p_browse_data; int count; + uint16_t min_len = 3; p_result->pdu = *p++; AVRC_TRACE_DEBUG("avrc_pars_browsing_cmd() pdu:0x%x", p_result->pdu); @@ -438,6 +445,7 @@ static tAVRC_STS avrc_pars_browsing_cmd(tAVRC_MSG_BROWSE* p_msg, break; case AVRC_PDU_GET_FOLDER_ITEMS: /* 0x71 */ + min_len += 10; STREAM_TO_UINT8(p_result->get_items.scope, p); // To be modified later here (Scope) when all browsing commands are // supported @@ -458,6 +466,11 @@ static tAVRC_STS avrc_pars_browsing_cmd(tAVRC_MSG_BROWSE* p_msg, if (buf_len < (count << 2)) p_result->get_items.attr_count = count = (buf_len >> 2); for (int idx = 0; idx < count; idx++) { + min_len += 4; + RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, + (p_msg->browse_len >= min_len), + "msg too short"); + BE_STREAM_TO_UINT32(p_result->get_items.p_attr_list[idx], p); } } @@ -474,6 +487,7 @@ static tAVRC_STS avrc_pars_browsing_cmd(tAVRC_MSG_BROWSE* p_msg, break; case AVRC_PDU_GET_ITEM_ATTRIBUTES: /* 0x73 */ + min_len += 12; BE_STREAM_TO_UINT8(p_result->get_attrs.scope, p); if (p_result->get_attrs.scope > AVRC_SCOPE_NOW_PLAYING) { status = AVRC_STS_BAD_SCOPE; @@ -490,6 +504,11 @@ static tAVRC_STS avrc_pars_browsing_cmd(tAVRC_MSG_BROWSE* p_msg, p_result->get_attrs.attr_count = count = (buf_len >> 2); for (int idx = 0, count = 0; idx < p_result->get_attrs.attr_count; idx++) { + min_len += 4; + RETURN_STATUS_IF_FALSE(AVRC_STS_BAD_CMD, + (p_msg->browse_len >= min_len), + "msg too short"); + BE_STREAM_TO_UINT32(p_result->get_attrs.p_attr_list[count], p); if (AVRC_IS_VALID_MEDIA_ATTRIBUTE( p_result->get_attrs.p_attr_list[count])) {