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

Commit 5db08f20 authored by Jakub Pawlowski's avatar Jakub Pawlowski Committed by Jakub Pawłowski
Browse files

Reset sec_dev_pending on Pairing retry for LE devices

Currently there is a race condition happening for LE only devices:
If pairing is cancelled, and immediately restarted before link is
disconnected, we would delete it's keys on first disconnection.

This is because we miss a call to bta_dm_reset_sec_dev_pending.

BTA_DM_AUTH_CMPL_EVT event is generated when Classic device finish
pairing and have key for storage.
BTM_LE_KEY_EVT event is generated when LE device have some key for
storage.

In both cases, we should make a call to bta_dm_reset_sec_dev_pending,
currently we make this call only for Classic device.

Test: Fast Pair would some times cause this race condition, no good
steps for manual reproduction
Bug: 286968340
Change-Id: I962d3bb8d5c45d9dc2c8780a4f42eb57edda7898
parent 10dd3913
Loading
Loading
Loading
Loading
+24 −5
Original line number Diff line number Diff line
@@ -845,8 +845,11 @@ void bta_dm_close_acl(const RawAddress& bd_addr, bool remove_dev,
        break;
    }
    if (index != bta_dm_cb.device_list.count) {
      if (remove_dev)
      if (remove_dev) {
        LOG_INFO("Setting remove_dev_pending for %s",
                 ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
        bta_dm_cb.device_list.peer_device[index].remove_dev_pending = true;
      }
    } else {
      APPL_TRACE_ERROR("unknown device, remove ACL failed");
    }
@@ -2901,6 +2904,8 @@ static void bta_dm_acl_down(const RawAddress& bd_addr,
    }
  }
  if (remove_device) {
    LOG_INFO("remove_dev_pending actually removing %s",
             ADDRESS_TO_LOGGABLE_CSTR(bd_addr));
    bta_dm_process_remove_device_no_callback(bd_addr);
  }

@@ -3066,8 +3071,13 @@ static void bta_dm_delay_role_switch_cback(UNUSED_ATTR void* data) {
 ******************************************************************************/
static void bta_dm_reset_sec_dev_pending(const RawAddress& remote_bd_addr) {
  for (size_t i = 0; i < bta_dm_cb.device_list.count; i++) {
    if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
      bta_dm_cb.device_list.peer_device[i].remove_dev_pending = false;
    auto& dev = bta_dm_cb.device_list.peer_device[i];
    if (dev.peer_bdaddr == remote_bd_addr) {
      if (dev.remove_dev_pending) {
        LOG_INFO("Clearing remove_dev_pending for %s",
                 ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr));
        dev.remove_dev_pending = false;
      }
      return;
    }
  }
@@ -3094,8 +3104,11 @@ static void bta_dm_remove_sec_dev_entry(const RawAddress& remote_bd_addr) {
        __func__);
    BTM_SecClearSecurityFlags(remote_bd_addr);
    for (int i = 0; i < bta_dm_cb.device_list.count; i++) {
      if (bta_dm_cb.device_list.peer_device[i].peer_bdaddr == remote_bd_addr) {
        bta_dm_cb.device_list.peer_device[i].remove_dev_pending = TRUE;
      auto& dev = bta_dm_cb.device_list.peer_device[i];
      if (dev.peer_bdaddr == remote_bd_addr) {
        LOG_INFO("Setting remove_dev_pending for %s",
                 ADDRESS_TO_LOGGABLE_CSTR(dev.peer_bdaddr));
        dev.remove_dev_pending = TRUE;
        break;
      }
    }
@@ -3968,6 +3981,12 @@ static uint8_t bta_dm_ble_smp_cback(tBTM_LE_EVT event, const RawAddress& bda,
      sec_event.ble_key.key_type = p_data->key.key_type;
      sec_event.ble_key.p_key_value = p_data->key.p_key_value;
      bta_dm_cb.p_sec_cback(BTA_DM_BLE_KEY_EVT, &sec_event);

      // Setting remove_dev_pending flag to false, where it will avoid deleting
      // the security device record when the ACL connection link goes down in
      // case of reconnection.
      if (bta_dm_cb.device_list.count) bta_dm_reset_sec_dev_pending(bda);

      break;

    case BTM_LE_COMPLT_EVT: