mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
fix(bt/bluedroid): fixed potential OOB read in the reporting handler
Thanks to Luigino Camastra and Pavel Kohout from Aisle Research as co-reporters for discovering and reporting this issue.
This commit is contained in:
@@ -351,13 +351,18 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
|
||||
UINT8 *p_start = p;
|
||||
UINT32 ssrc;
|
||||
UINT8 o_v, o_p, o_cc;
|
||||
UINT32 min_len = 0;
|
||||
AVDT_REPORT_TYPE pt;
|
||||
tAVDT_REPORT_DATA report, *p_rpt;
|
||||
tAVDT_REPORT_DATA report;
|
||||
|
||||
AVDT_TRACE_DEBUG( "avdt_scb_hdl_report");
|
||||
if (p_scb->cs.p_report_cback) {
|
||||
p_rpt = &report;
|
||||
/* parse report packet header */
|
||||
min_len += 8;
|
||||
if (len < min_len) {
|
||||
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
|
||||
goto avdt_scb_hdl_report_exit;
|
||||
}
|
||||
AVDT_MSG_PRS_RPT_OCTET1(p, o_v, o_p, o_cc);
|
||||
pt = *p++;
|
||||
p += 2;
|
||||
@@ -370,6 +375,11 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
|
||||
|
||||
switch (pt) {
|
||||
case AVDT_RTCP_PT_SR: /* the packet type - SR (Sender Report) */
|
||||
min_len += 20;
|
||||
if (len < min_len) {
|
||||
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
|
||||
goto avdt_scb_hdl_report_exit;
|
||||
}
|
||||
BE_STREAM_TO_UINT32(report.sr.ntp_sec, p);
|
||||
BE_STREAM_TO_UINT32(report.sr.ntp_frac, p);
|
||||
BE_STREAM_TO_UINT32(report.sr.rtp_time, p);
|
||||
@@ -378,6 +388,11 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
|
||||
break;
|
||||
|
||||
case AVDT_RTCP_PT_RR: /* the packet type - RR (Receiver Report) */
|
||||
min_len += 20;
|
||||
if (len < min_len) {
|
||||
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
|
||||
goto avdt_scb_hdl_report_exit;
|
||||
}
|
||||
report.rr.frag_lost = *p;
|
||||
BE_STREAM_TO_UINT32(report.rr.packet_lost, p);
|
||||
report.rr.packet_lost &= 0xFFFFFF;
|
||||
@@ -388,11 +403,32 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
|
||||
break;
|
||||
|
||||
case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */
|
||||
if (*p == AVDT_RTCP_SDES_CNAME) {
|
||||
p_rpt = (tAVDT_REPORT_DATA *)(p + 2);
|
||||
min_len += 1;
|
||||
if (len < min_len) {
|
||||
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
|
||||
goto avdt_scb_hdl_report_exit;
|
||||
}
|
||||
uint8_t sdes_type;
|
||||
BE_STREAM_TO_UINT8(sdes_type, p);
|
||||
if (sdes_type == AVDT_RTCP_SDES_CNAME) {
|
||||
min_len += 1;
|
||||
if (len < min_len) {
|
||||
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
|
||||
goto avdt_scb_hdl_report_exit;
|
||||
}
|
||||
uint8_t name_length;
|
||||
BE_STREAM_TO_UINT8(name_length, p);\
|
||||
if ((name_length > len - min_len) || (name_length > AVDT_MAX_CNAME_SIZE)) {
|
||||
result = AVDT_BAD_PARAMS;
|
||||
} else {
|
||||
BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length);
|
||||
}
|
||||
} else {
|
||||
AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d %s\n",
|
||||
ssrc, o_cc, *p, *(p + 1), p + 2);
|
||||
if (len < min_len + 1) {
|
||||
AVDT_TRACE_WARNING("hdl packet length %u too short: must be at least %u", len, min_len);
|
||||
goto avdt_scb_hdl_report_exit;
|
||||
}
|
||||
AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d\n", ssrc, o_cc, sdes_type, *p);
|
||||
result = AVDT_BUSY;
|
||||
}
|
||||
break;
|
||||
@@ -403,10 +439,12 @@ UINT8 *avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
|
||||
}
|
||||
|
||||
if (result == AVDT_SUCCESS) {
|
||||
(*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, p_rpt);
|
||||
(*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, &report);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
avdt_scb_hdl_report_exit:
|
||||
p_start += len;
|
||||
return p_start;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user