*
******************************************************************************/
+#include <cutils/log.h>
#include <string.h>
#include "a2dp_codec_api.h"
#include "avdt_api.h"
uint16_t offset;
uint16_t ex_len;
uint8_t pad_len = 0;
+ uint16_t len = p_data->p_pkt->len;
p = p_start = (uint8_t*)(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);
p += 4;
/* 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_t)(p - p_start);
-
/* adjust length for any padding at end of packet */
if (o_p) {
/* padding length in last byte of packet */
osi_free_and_reset((void**)&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);
+ osi_free_and_reset((void**)&p_data->p_pkt);
}
#if (AVDT_REPORTING == TRUE)
uint8_t* p_start = p;
uint32_t ssrc;
uint8_t o_v, o_p, o_cc;
+ uint16_t min_len = 0;
AVDT_REPORT_TYPE pt;
tAVDT_REPORT_DATA report;
AVDT_TRACE_DEBUG("%s", __func__);
if (p_scb->cs.p_report_cback) {
/* 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;
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);
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;
case AVDT_RTCP_PT_SDES: /* the packet type - SDES (Source Description) */
uint8_t sdes_type;
+ min_len += 1;
+ 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_UINT8(sdes_type, p);
if (sdes_type == AVDT_RTCP_SDES_CNAME) {
uint8_t name_length;
+ min_len += 1;
+ 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_UINT8(name_length, p);
if (name_length > len - 2 || name_length > AVDT_MAX_CNAME_SIZE) {
result = AVDT_BAD_PARAMS;
BE_STREAM_TO_ARRAY(p, &(report.cname[0]), name_length);
}
} 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;
if (result == AVDT_SUCCESS)
(*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;
}