Commit message: None
CVE: CVE-2018-9508
CWE: CWE-125
Vulnerability description: In smp_process_keypress_notification of smp_act.cc, there is a possible out of bounds read due to an incorrect bounds check. This could lead to remote information disclosure over Bluetooth 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 ID: A-111936834

Project: Android

static bool pts_test_send_authentication_complete_failure(tSMP_CB* p_cb) {
 uint8_t reason = p_cb->cert_failure;
 if (reason == SMP_PAIR_AUTH_FAIL || reason == SMP_PAIR_FAIL_UNKNOWN ||
      reason == SMP_PAIR_NOT_SUPPORT || reason == SMP_PASSKEY_ENTRY_FAIL ||
      reason == SMP_REPEATED_ATTEMPTS) {
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
 return true;
 }
 return false;
}

Project: Android

void smp_br_process_link_key(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tSMP_STATUS status = SMP_PAIR_FAIL_UNKNOWN;

  SMP_TRACE_DEBUG("%s", __func__);
 if (!smp_calculate_long_term_key_from_link_key(p_cb)) {
    SMP_TRACE_ERROR("%s: failed", __func__);
    smp_sm_event(p_cb, SMP_BR_AUTH_CMPL_EVT, &status);
 return;
 }

  SMP_TRACE_DEBUG("%s: LTK derivation from LK successfully completed",
                  __func__);
  smp_save_secure_connections_long_term_key(p_cb);
  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, false);
  smp_br_select_next_key(p_cb, NULL);
}

Project: Android

void smp_enc_cmpl(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 uint8_t enc_enable = *(uint8_t*)p_data;
 uint8_t reason = enc_enable ? SMP_SUCCESS : SMP_ENC_FAIL;

  SMP_TRACE_DEBUG("%s", __func__);
  smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
}

Project: Android

void smp_proc_enc_info(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 uint8_t* p = (uint8_t*)p_data;

  SMP_TRACE_DEBUG("%s", __func__);
  STREAM_TO_ARRAY(p_cb->ltk, p, BT_OCTET16_LEN);

  smp_key_distribution(p_cb, NULL);
}

Project: Android

void smp_proc_master_id(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 uint8_t* p = (uint8_t*)p_data;
  tBTM_LE_PENC_KEYS le_key;

  SMP_TRACE_DEBUG("%s", __func__);
  smp_update_key_mask(p_cb, SMP_SEC_KEY_TYPE_ENC, true);

  STREAM_TO_UINT16(le_key.ediv, p);
  STREAM_TO_ARRAY(le_key.rand, p, BT_OCTET8_LEN);

 /* store the encryption keys from peer device */
  memcpy(le_key.ltk, p_cb->ltk, BT_OCTET16_LEN);
  le_key.sec_level = p_cb->sec_level;
  le_key.key_size = p_cb->loc_enc_size;

 if ((p_cb->peer_auth_req & SMP_AUTH_BOND) &&
 (p_cb->loc_auth_req & SMP_AUTH_BOND))
    btm_sec_save_le_key(p_cb->pairing_bda, BTM_LE_KEY_PENC,
 (tBTM_LE_KEY_VALUE*)&le_key, true);

  smp_key_distribution(p_cb, NULL);
}

Project: Android

void smp_proc_rand(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 uint8_t* p = (uint8_t*)p_data;
 uint8_t reason = SMP_INVALID_PARAMETERS;

  SMP_TRACE_DEBUG("%s", __func__);

 if (smp_command_has_invalid_parameters(p_cb)) {
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
 return;
 }

 /* save the SRand for comparison */
  STREAM_TO_ARRAY(p_cb->rrand, p, BT_OCTET16_LEN);
}

Project: Android

void smp_process_pairing_commitment(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
 uint8_t* p = (uint8_t*)p_data;
 uint8_t reason = SMP_INVALID_PARAMETERS;

  SMP_TRACE_DEBUG("%s", __func__);

 if (smp_command_has_invalid_parameters(p_cb)) {
    smp_sm_event(p_cb, SMP_AUTH_CMPL_EVT, &reason);
 return;
 }

  p_cb->flags |= SMP_PAIR_FLAG_HAVE_PEER_COMM;

 if (p != NULL) {
    STREAM_TO_ARRAY(p_cb->remote_commitment, p, BT_OCTET16_LEN);
 }
}

Project: Android

void smp_send_app_cback(tSMP_CB* p_cb, tSMP_INT_DATA* p_data) {
  tSMP_EVT_DATA cb_data;
  tSMP_STATUS callback_rc;
  SMP_TRACE_DEBUG("%s p_cb->cb_evt=%d", __func__, p_cb->cb_evt);
 if (p_cb->p_callback && p_cb->cb_evt != 0) {
 switch (p_cb->cb_evt) {
 case SMP_IO_CAP_REQ_EVT:
        cb_data.io_req.auth_req = p_cb->peer_auth_req;
        cb_data.io_req.oob_data = SMP_OOB_NONE;
        cb_data.io_req.io_cap = SMP_DEFAULT_IO_CAPS;
        cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE;
        cb_data.io_req.init_keys = p_cb->local_i_key;
        cb_data.io_req.resp_keys = p_cb->local_r_key;
        SMP_TRACE_WARNING("io_cap = %d", cb_data.io_req.io_cap);
 break;

 case SMP_NC_REQ_EVT:
        cb_data.passkey = p_data->passkey;
 break;
 case SMP_SC_OOB_REQ_EVT:
        cb_data.req_oob_type = p_data->req_oob_type;
 break;
 case SMP_SC_LOC_OOB_DATA_UP_EVT:
        cb_data.loc_oob_data = p_cb->sc_oob_data.loc_oob_data;
 break;

 case SMP_BR_KEYS_REQ_EVT:
        cb_data.io_req.auth_req = 0;
        cb_data.io_req.oob_data = SMP_OOB_NONE;
        cb_data.io_req.io_cap = 0;
        cb_data.io_req.max_key_size = SMP_MAX_ENC_KEY_SIZE;
        cb_data.io_req.init_keys = SMP_BR_SEC_DEFAULT_KEY;
        cb_data.io_req.resp_keys = SMP_BR_SEC_DEFAULT_KEY;
 break;

 default:
 break;
 }

    callback_rc =
 (*p_cb->p_callback)(p_cb->cb_evt, p_cb->pairing_bda, &cb_data);

    SMP_TRACE_DEBUG("%s: callback_rc=%d  p_cb->cb_evt=%d", __func__,
                    callback_rc, p_cb->cb_evt);

 if (callback_rc == SMP_SUCCESS) {
 switch (p_cb->cb_evt) {
 case SMP_IO_CAP_REQ_EVT:
          p_cb->loc_auth_req = cb_data.io_req.auth_req;
          p_cb->local_io_capability = cb_data.io_req.io_cap;
          p_cb->loc_oob_flag = cb_data.io_req.oob_data;
          p_cb->loc_enc_size = cb_data.io_req.max_key_size;
          p_cb->local_i_key = cb_data.io_req.init_keys;
          p_cb->local_r_key = cb_data.io_req.resp_keys;

 if (!(p_cb->loc_auth_req & SMP_AUTH_BOND)) {
            SMP_TRACE_WARNING("Non bonding: No keys will be exchanged");
            p_cb->local_i_key = 0;
            p_cb->local_r_key = 0;
 }

          SMP_TRACE_WARNING(
 "rcvd auth_req: 0x%02x, io_cap: %d "
 "loc_oob_flag: %d loc_enc_size: %d, "
 "local_i_key: 0x%02x, local_r_key: 0x%02x",
              p_cb->loc_auth_req, p_cb->local_io_capability, p_cb->loc_oob_flag,
              p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key);

          p_cb->secure_connections_only_mode_required =
 (btm_cb.security_mode == BTM_SEC_MODE_SC) ? true : false;

 if (p_cb->secure_connections_only_mode_required) {
            p_cb->loc_auth_req |= SMP_SC_SUPPORT_BIT;
 }

 if (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) ||
              lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_4_2) ||
              interop_match_addr(INTEROP_DISABLE_LE_SECURE_CONNECTIONS,
 (const RawAddress*)&p_cb->pairing_bda)) {
            p_cb->loc_auth_req &= ~SMP_KP_SUPPORT_BIT;
            p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
            p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;
 }

 if (lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_5_0)) {
            p_cb->loc_auth_req &= ~SMP_H7_SUPPORT_BIT;
 }

          SMP_TRACE_WARNING(
 "set auth_req: 0x%02x, local_i_key: 0x%02x, local_r_key: 0x%02x",
              p_cb->loc_auth_req, p_cb->local_i_key, p_cb->local_r_key);

          smp_sm_event(p_cb, SMP_IO_RSP_EVT, NULL);
 break;

 case SMP_BR_KEYS_REQ_EVT:
          p_cb->loc_enc_size = cb_data.io_req.max_key_size;
          p_cb->local_i_key = cb_data.io_req.init_keys;
          p_cb->local_r_key = cb_data.io_req.resp_keys;
          p_cb->loc_auth_req |= SMP_H7_SUPPORT_BIT;

          p_cb->local_i_key &= ~SMP_SEC_KEY_TYPE_LK;
          p_cb->local_r_key &= ~SMP_SEC_KEY_TYPE_LK;

          SMP_TRACE_WARNING(
 "for SMP over BR max_key_size: 0x%02x, local_i_key: 0x%02x, "
 "local_r_key: 0x%02x, p_cb->loc_auth_req: 0x%02x",
              p_cb->loc_enc_size, p_cb->local_i_key, p_cb->local_r_key,
              p_cb->loc_auth_req);

          smp_br_state_machine_event(p_cb, SMP_BR_KEYS_RSP_EVT, NULL);
 break;
 }
 }
 }

 if (!p_cb->cb_evt && p_cb->discard_sec_req) {
    p_cb->discard_sec_req = false;
    smp_sm_event(p_cb, SMP_DISCARD_SEC_REQ_EVT, NULL);
 }

  SMP_TRACE_DEBUG("%s: return", __func__);
}