summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUgo Yu <ugoyu@google.com>2018-10-30 01:57:06 +0800
committerTim Schumacher <timschumi@gmx.de>2019-02-10 12:16:09 +0100
commit07e8472579a29d17b630d1c43735245934ba51dd (patch)
tree69c991ae693014dc4f629522e23d5c76bf3cc9ce
parent409e6b9b92ed7104ce03ffb9842f1960461db6b7 (diff)
downloadandroid_system_bt-07e8472579a29d17b630d1c43735245934ba51dd.tar.gz
android_system_bt-07e8472579a29d17b630d1c43735245934ba51dd.tar.bz2
android_system_bt-07e8472579a29d17b630d1c43735245934ba51dd.zip
Fix possible OOB when AVDT data channel recive ACL data
Bug: 111450156 Change-Id: Id23eeedcb7bde5866cd53a2f7f1c30f27c5352f6 (cherry picked from commit b0125caafec2183d73fc899ce5a8aee43a6e54af) (cherry picked from commit ad4098c340b52acdb0f48fd3e2612d810e71f4c4) CVE-2018-9588
-rw-r--r--stack/avdt/avdt_scb_act.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/stack/avdt/avdt_scb_act.c b/stack/avdt/avdt_scb_act.c
index ce25b2eae..4fc92aa85 100644
--- a/stack/avdt/avdt_scb_act.c
+++ b/stack/avdt/avdt_scb_act.c
@@ -23,6 +23,7 @@
*
******************************************************************************/
+#include <cutils/log.h>
#include <string.h>
#include "bt_types.h"
#include "bt_target.h"
@@ -250,10 +251,15 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
UINT16 offset;
UINT16 ex_len;
UINT8 pad_len = 0;
+ UINT16 len;
+ len = p_data->p_pkt->len;
p = p_start = (UINT8 *)(p_data->p_pkt + 1) + p_data->p_pkt->offset;
/* parse media packet header */
+ offset = 12;
+ // AVDT_MSG_PRS_OCTET1(1) + AVDT_MSG_PRS_M_PT(1) + UINT16(2) + UINT32(4) + 4
+ if (offset > len) goto length_error;
AVDT_MSG_PRS_OCTET1(p, o_v, o_p, o_x, o_cc);
AVDT_MSG_PRS_M_PT(p, m_pt, marker);
BE_STREAM_TO_UINT16(seq, p);
@@ -263,19 +269,20 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
UNUSED(o_v);
/* skip over any csrc's in packet */
+ offset += o_cc * 4;
p += o_cc * 4;
/* check for and skip over extension header */
if (o_x)
{
+ offset += 4;
+ if (offset > len) goto length_error;
p += 2;
BE_STREAM_TO_UINT16(ex_len, p);
+ offset += ex_len * 4;
p += ex_len * 4;
}
- /* save our new offset */
- offset = (UINT16) (p - p_start);
-
/* adjust length for any padding at end of packet */
if (o_p)
{
@@ -320,6 +327,12 @@ void avdt_scb_hdl_pkt_no_frag(tAVDT_SCB *p_scb, tAVDT_SCB_EVT *p_data)
GKI_freebuf(p_data->p_pkt);
}
}
+ return;
+length_error:
+ android_errorWriteLog(0x534e4554, "111450156");
+ AVDT_TRACE_WARNING("%s: hdl packet length %d too short: must be at least %d",
+ __func__, len, offset);
+ GKI_freebuf(p_data->p_pkt);
}
#if AVDT_REPORTING == TRUE
@@ -338,6 +351,7 @@ 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;
+ UINT16 min_len = 0;
AVDT_REPORT_TYPE pt;
tAVDT_REPORT_DATA report, *p_rpt;
@@ -346,6 +360,14 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
{
p_rpt = &report;
/* parse report packet header */
+ min_len += 8;
+ if (min_len > len) {
+ android_errorWriteLog(0x534e4554, "111450156");
+ AVDT_TRACE_WARNING(
+ "%s: hdl packet length %d too short: must be at least %d", __func__,
+ 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;
@@ -357,6 +379,14 @@ 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 (min_len > len) {
+ android_errorWriteLog(0x534e4554, "111450156");
+ AVDT_TRACE_WARNING(
+ "%s: hdl packet length %d too short: must be at least %d",
+ __func__, 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);
@@ -365,6 +395,14 @@ 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 (min_len > len) {
+ android_errorWriteLog(0x534e4554, "111450156");
+ AVDT_TRACE_WARNING(
+ "%s: hdl packet length %d too short: must be at least %d",
+ __func__, 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;
@@ -377,10 +415,25 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */
if(*p == AVDT_RTCP_SDES_CNAME)
{
+ min_len += sizeof(tAVDT_REPORT_DATA) + 2;
+ if (min_len > len) {
+ android_errorWriteLog(0x534e4554, "111450156");
+ AVDT_TRACE_WARNING(
+ "%s: hdl packet length %d too short: must be at least %d",
+ __func__, len, min_len);
+ goto avdt_scb_hdl_report_exit;
+ }
p_rpt = (tAVDT_REPORT_DATA *)(p+2);
}
else
{
+ if (min_len + 1 > len) {
+ android_errorWriteLog(0x534e4554, "111450156");
+ AVDT_TRACE_WARNING(
+ "%s: hdl packet length %d too short: must be at least %d",
+ __func__, len, min_len + 2);
+ goto avdt_scb_hdl_report_exit;
+ }
AVDT_TRACE_WARNING( " - SDES SSRC=0x%08x sc=%d %d len=%d %s",
ssrc, o_cc, *p, *(p+1), p+2);
result = AVDT_BUSY;
@@ -396,6 +449,7 @@ UINT8 * avdt_scb_hdl_report(tAVDT_SCB *p_scb, UINT8 *p, UINT16 len)
(*p_scb->cs.p_report_cback)(avdt_scb_to_hdl(p_scb), pt, p_rpt);
}
+avdt_scb_hdl_report_exit:
p_start += len;
return p_start;
}