Commit message: None
CVE: CVE-2018-9503
CWE: CWE-125
Vulnerability description: In rfc_process_mx_message of rfc_ts_frames.cc, there is a possible out of bounds read due to a missing bounds check. This could lead to remote information disclosure with no additional execution privileges needed. User interaction is not needed for exploitation. Product: Android Versions: Android-7.0 Android-7.1.1 Android-7.1.2 Android-8.0 Android-8.1 Android-9.0 Android ID: A-80432928

Project: Android

uint8_t rfc_parse_data(tRFC_MCB* p_mcb, MX_FRAME* p_frame, BT_HDR* p_buf) {
 uint8_t ead, eal, fcs;
 uint8_t* p_data = (uint8_t*)(p_buf + 1) + p_buf->offset;
 uint8_t* p_start = p_data;
 uint16_t len;

 if (p_buf->len < RFCOMM_CTRL_FRAME_LEN) {
    RFCOMM_TRACE_ERROR("Bad Length1: %d", p_buf->len);
 return (RFC_EVENT_BAD_FRAME);
 }

  RFCOMM_PARSE_CTRL_FIELD(ead, p_frame->cr, p_frame->dlci, p_data);
 if (!ead) {
    RFCOMM_TRACE_ERROR("Bad Address(EA must be 1)");

     return (RFC_EVENT_BAD_FRAME);
   }
   RFCOMM_PARSE_TYPE_FIELD(p_frame->type, p_frame->pf, p_data);
  RFCOMM_PARSE_LEN_FIELD(eal, len, p_data);
 
   p_buf->len -= (3 + !ead + !eal + 1); /* Additional 1 for FCS */
   p_buf->offset += (3 + !ead + !eal);

 /* handle credit if credit based flow control */
 if ((p_mcb->flow == PORT_FC_CREDIT) && (p_frame->type == RFCOMM_UIH) &&
 (p_frame->dlci != RFCOMM_MX_DLCI) && (p_frame->pf == 1)) {
    p_frame->credit = *p_data++;
    p_buf->len--;
    p_buf->offset++;
 } else
    p_frame->credit = 0;

 if (p_buf->len != len) {
    RFCOMM_TRACE_ERROR("Bad Length2 %d %d", p_buf->len, len);
 return (RFC_EVENT_BAD_FRAME);
 }

  fcs = *(p_data + len);

 /* All control frames that we are sending are sent with P=1, expect */
 /* reply with F=1 */
 /* According to TS 07.10 spec ivalid frames are discarded without */
 /* notification to the sender */
 switch (p_frame->type) {
 case RFCOMM_SABME:
 if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) ||
 !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) ||
 !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
        RFCOMM_TRACE_ERROR("Bad SABME");
 return (RFC_EVENT_BAD_FRAME);
 } else
 return (RFC_EVENT_SABME);

 case RFCOMM_UA:
 if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) ||
 !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) ||
 !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
        RFCOMM_TRACE_ERROR("Bad UA");
 return (RFC_EVENT_BAD_FRAME);
 } else
 return (RFC_EVENT_UA);

 case RFCOMM_DM:
 if (RFCOMM_FRAME_IS_CMD(p_mcb->is_initiator, p_frame->cr) || len ||
 !RFCOMM_VALID_DLCI(p_frame->dlci) ||
 !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
        RFCOMM_TRACE_ERROR("Bad DM");
 return (RFC_EVENT_BAD_FRAME);
 } else
 return (RFC_EVENT_DM);

 case RFCOMM_DISC:
 if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr) ||
 !p_frame->pf || len || !RFCOMM_VALID_DLCI(p_frame->dlci) ||
 !rfc_check_fcs(RFCOMM_CTRL_FRAME_LEN, p_start, fcs)) {
        RFCOMM_TRACE_ERROR("Bad DISC");
 return (RFC_EVENT_BAD_FRAME);
 } else
 return (RFC_EVENT_DISC);

 case RFCOMM_UIH:
 if (!RFCOMM_VALID_DLCI(p_frame->dlci)) {
        RFCOMM_TRACE_ERROR("Bad UIH - invalid DLCI");
 return (RFC_EVENT_BAD_FRAME);
 } else if (!rfc_check_fcs(2, p_start, fcs)) {
        RFCOMM_TRACE_ERROR("Bad UIH - FCS");
 return (RFC_EVENT_BAD_FRAME);
 } else if (RFCOMM_FRAME_IS_RSP(p_mcb->is_initiator, p_frame->cr)) {
 /* we assume that this is ok to allow bad implementations to work */
        RFCOMM_TRACE_ERROR("Bad UIH - response");
 return (RFC_EVENT_UIH);
 } else
 return (RFC_EVENT_UIH);
 }

 return (RFC_EVENT_BAD_FRAME);
}