Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bdd3fc5 authored by Pavlin Radoslavov's avatar Pavlin Radoslavov
Browse files

Add missing packet length checks while parsing BNEP control packets

Bug: 63146237
Test: External script
Change-Id: Ie778f3c99df81c85ed988f3af89b4edbcc2eeb99
Merged-In: Ie778f3c99df81c85ed988f3af89b4edbcc2eeb99
(cherry picked from commit 7feaeb006941a1494d7cdc0a2ffc4bb1004b38b4)
parent 436b7170
Loading
Loading
Loading
Loading
+61 −22
Original line number Diff line number Diff line
@@ -714,25 +714,41 @@ void bnep_process_setup_conn_responce(tBNEP_CONN* p_bcb, uint8_t* p_setup) {
uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
                                     uint16_t* rem_len, bool is_ext) {
  uint8_t control_type;
  bool bad_pkt = false;
  uint16_t len, ext_len = 0;

  if (p == NULL || rem_len == NULL) {
    if (rem_len != NULL) *rem_len = 0;
    BNEP_TRACE_DEBUG("%s: invalid packet: p = %p rem_len = %p", __func__, p,
                     rem_len);
    return NULL;
  }
  uint16_t rem_len_orig = *rem_len;

  if (is_ext) {
    if (*rem_len < 1) goto bad_packet_length;
    ext_len = *p++;
    *rem_len = *rem_len - 1;
  }

  if (*rem_len < 1) goto bad_packet_length;
  control_type = *p++;
  *rem_len = *rem_len - 1;

  BNEP_TRACE_EVENT(
      "BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d",
      *rem_len, is_ext, control_type);
      "%s: BNEP processing control packet rem_len %d, is_ext %d, ctrl_type %d",
      __func__, *rem_len, is_ext, control_type);

  switch (control_type) {
    case BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD:
      BNEP_TRACE_ERROR("BNEP Received Cmd not understood for ctl pkt type: %d",
                       *p);
      if (*rem_len < 1) {
        BNEP_TRACE_ERROR(
            "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD with bad length",
            __func__);
        goto bad_packet_length;
      }
      BNEP_TRACE_ERROR(
          "%s: Received BNEP_CONTROL_COMMAND_NOT_UNDERSTOOD for pkt type: %d",
          __func__, *p);
      p++;
      *rem_len = *rem_len - 1;
      break;
@@ -740,9 +756,10 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
    case BNEP_SETUP_CONNECTION_REQUEST_MSG:
      len = *p++;
      if (*rem_len < ((2 * len) + 1)) {
        bad_pkt = true;
        BNEP_TRACE_ERROR("BNEP Received Setup message with bad length");
        break;
        BNEP_TRACE_ERROR(
            "%s: Received BNEP_SETUP_CONNECTION_REQUEST_MSG with bad length",
            __func__);
        goto bad_packet_length;
      }
      if (!is_ext) bnep_process_setup_conn_req(p_bcb, p, (uint8_t)len);
      p += (2 * len);
@@ -750,6 +767,12 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
      break;

    case BNEP_SETUP_CONNECTION_RESPONSE_MSG:
      if (*rem_len < 2) {
        BNEP_TRACE_ERROR(
            "%s: Received BNEP_SETUP_CONNECTION_RESPONSE_MSG with bad length",
            __func__);
        goto bad_packet_length;
      }
      if (!is_ext) bnep_process_setup_conn_responce(p_bcb, p);
      p += 2;
      *rem_len = *rem_len - 2;
@@ -758,9 +781,10 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
    case BNEP_FILTER_NET_TYPE_SET_MSG:
      BE_STREAM_TO_UINT16(len, p);
      if (*rem_len < (len + 2)) {
        bad_pkt = true;
        BNEP_TRACE_ERROR("BNEP Received Filter set message with bad length");
        break;
        BNEP_TRACE_ERROR(
            "%s: Received BNEP_FILTER_NET_TYPE_SET_MSG with bad length",
            __func__);
        goto bad_packet_length;
      }
      bnepu_process_peer_filter_set(p_bcb, p, len);
      p += len;
@@ -768,6 +792,12 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
      break;

    case BNEP_FILTER_NET_TYPE_RESPONSE_MSG:
      if (*rem_len < 2) {
        BNEP_TRACE_ERROR(
            "%s: Received BNEP_FILTER_NET_TYPE_RESPONSE_MSG with bad length",
            __func__);
        goto bad_packet_length;
      }
      bnepu_process_peer_filter_rsp(p_bcb, p);
      p += 2;
      *rem_len = *rem_len - 2;
@@ -776,10 +806,10 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
    case BNEP_FILTER_MULTI_ADDR_SET_MSG:
      BE_STREAM_TO_UINT16(len, p);
      if (*rem_len < (len + 2)) {
        bad_pkt = true;
        BNEP_TRACE_ERROR(
            "BNEP Received Multicast Filter Set message with bad length");
        break;
            "%s: Received BNEP_FILTER_MULTI_ADDR_SET_MSG with bad length",
            __func__);
        goto bad_packet_length;
      }
      bnepu_process_peer_multicast_filter_set(p_bcb, p, len);
      p += len;
@@ -787,30 +817,39 @@ uint8_t* bnep_process_control_packet(tBNEP_CONN* p_bcb, uint8_t* p,
      break;

    case BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG:
      if (*rem_len < 2) {
        BNEP_TRACE_ERROR(
            "%s: Received BNEP_FILTER_MULTI_ADDR_RESPONSE_MSG with bad length",
            __func__);
        goto bad_packet_length;
      }
      bnepu_process_multicast_filter_rsp(p_bcb, p);
      p += 2;
      *rem_len = *rem_len - 2;
      break;

    default:
      BNEP_TRACE_ERROR("BNEP - bad ctl pkt type: %d", control_type);
      BNEP_TRACE_ERROR("%s: BNEP - bad ctl pkt type: %d", __func__,
                       control_type);
      bnep_send_command_not_understood(p_bcb, control_type);
      if (is_ext) {
        if (*rem_len < (ext_len - 1)) {
          goto bad_packet_length;
        }
        p += (ext_len - 1);
        *rem_len -= (ext_len - 1);
      }
      break;
  }
  return p;

  if (bad_pkt) {
    BNEP_TRACE_ERROR("BNEP - bad ctl pkt length: %d", *rem_len);
bad_packet_length:
  BNEP_TRACE_ERROR("%s: bad control packet length: original=%d remaining=%d",
                   __func__, rem_len_orig, *rem_len);
  *rem_len = 0;
  return NULL;
}

  return p;
}

/*******************************************************************************
 *
 * Function         bnepu_process_peer_filter_set