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

Commit 6dd4ccec authored by Jakub Tyszkowski's avatar Jakub Tyszkowski
Browse files

IsoManager: Protect against the usage when not started

Assume the caller will not check if IsoManager::IsRunning() and protect
the API call against null pointer dereference.

Bug: 350894286
Test: atest net_test_btm_iso
Flag: EXEMPT; Non-functional change, covered with unit tests
Change-Id: I0fd28575b44f1ef56f1ce40cd6c1aa22a7b46a71
parent b0acd0f4
Loading
Loading
Loading
Loading
+39 −13
Original line number Original line Diff line number Diff line
@@ -56,36 +56,52 @@ struct IsoManager::impl {
IsoManager::IsoManager() : pimpl_(std::make_unique<impl>(*this)) {}
IsoManager::IsoManager() : pimpl_(std::make_unique<impl>(*this)) {}


void IsoManager::RegisterCigCallbacks(CigCallbacks* callbacks) const {
void IsoManager::RegisterCigCallbacks(CigCallbacks* callbacks) const {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->handle_register_cis_callbacks(callbacks);
    pimpl_->iso_impl_->handle_register_cis_callbacks(callbacks);
  }
  }
}


void IsoManager::RegisterBigCallbacks(BigCallbacks* callbacks) const {
void IsoManager::RegisterBigCallbacks(BigCallbacks* callbacks) const {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->handle_register_big_callbacks(callbacks);
    pimpl_->iso_impl_->handle_register_big_callbacks(callbacks);
  }
  }
}


void IsoManager::RegisterOnIsoTrafficActiveCallback(void callback(bool)) const {
void IsoManager::RegisterOnIsoTrafficActiveCallback(void callback(bool)) const {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->handle_register_on_iso_traffic_active_callback(callback);
    pimpl_->iso_impl_->handle_register_on_iso_traffic_active_callback(callback);
  }
  }
}


void IsoManager::CreateCig(uint8_t cig_id, struct iso_manager::cig_create_params cig_params) {
void IsoManager::CreateCig(uint8_t cig_id, struct iso_manager::cig_create_params cig_params) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->create_cig(cig_id, std::move(cig_params));
    pimpl_->iso_impl_->create_cig(cig_id, std::move(cig_params));
  }
  }
}


void IsoManager::ReconfigureCig(uint8_t cig_id, struct iso_manager::cig_create_params cig_params) {
void IsoManager::ReconfigureCig(uint8_t cig_id, struct iso_manager::cig_create_params cig_params) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->reconfigure_cig(cig_id, std::move(cig_params));
    pimpl_->iso_impl_->reconfigure_cig(cig_id, std::move(cig_params));
  }
  }
}


void IsoManager::RemoveCig(uint8_t cig_id, bool force) {
void IsoManager::RemoveCig(uint8_t cig_id, bool force) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->remove_cig(cig_id, force);
    pimpl_->iso_impl_->remove_cig(cig_id, force);
  }
  }
}


void IsoManager::EstablishCis(struct iso_manager::cis_establish_params conn_params) {
void IsoManager::EstablishCis(struct iso_manager::cis_establish_params conn_params) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->establish_cis(std::move(conn_params));
    pimpl_->iso_impl_->establish_cis(std::move(conn_params));
  }
  }
}


void IsoManager::DisconnectCis(uint16_t cis_handle, uint8_t reason) {
void IsoManager::DisconnectCis(uint16_t cis_handle, uint8_t reason) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->disconnect_cis(cis_handle, reason);
    pimpl_->iso_impl_->disconnect_cis(cis_handle, reason);
  }
  }
}


int IsoManager::GetNumberOfActiveIso() {
int IsoManager::GetNumberOfActiveIso() {
  return pimpl_->iso_impl_ ? pimpl_->iso_impl_->get_number_of_active_iso() : 0;
  return pimpl_->iso_impl_ ? pimpl_->iso_impl_->get_number_of_active_iso() : 0;
@@ -93,24 +109,34 @@ int IsoManager::GetNumberOfActiveIso() {


void IsoManager::SetupIsoDataPath(uint16_t iso_handle,
void IsoManager::SetupIsoDataPath(uint16_t iso_handle,
                                  struct iso_manager::iso_data_path_params path_params) {
                                  struct iso_manager::iso_data_path_params path_params) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->setup_iso_data_path(iso_handle, std::move(path_params));
    pimpl_->iso_impl_->setup_iso_data_path(iso_handle, std::move(path_params));
  }
  }
}


void IsoManager::RemoveIsoDataPath(uint16_t iso_handle, uint8_t data_path_dir) {
void IsoManager::RemoveIsoDataPath(uint16_t iso_handle, uint8_t data_path_dir) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->remove_iso_data_path(iso_handle, data_path_dir);
    pimpl_->iso_impl_->remove_iso_data_path(iso_handle, data_path_dir);
  }
  }
}


void IsoManager::ReadIsoLinkQuality(uint16_t iso_handle) {
void IsoManager::ReadIsoLinkQuality(uint16_t iso_handle) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->read_iso_link_quality(iso_handle);
    pimpl_->iso_impl_->read_iso_link_quality(iso_handle);
  }
  }
}


void IsoManager::SendIsoData(uint16_t iso_handle, const uint8_t* data, uint16_t data_len) {
void IsoManager::SendIsoData(uint16_t iso_handle, const uint8_t* data, uint16_t data_len) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->send_iso_data(iso_handle, data, data_len);
    pimpl_->iso_impl_->send_iso_data(iso_handle, data, data_len);
  }
  }
}


void IsoManager::CreateBig(uint8_t big_id, struct iso_manager::big_create_params big_params) {
void IsoManager::CreateBig(uint8_t big_id, struct iso_manager::big_create_params big_params) {
  if (pimpl_->iso_impl_) {
    pimpl_->iso_impl_->create_big(big_id, std::move(big_params));
    pimpl_->iso_impl_->create_big(big_id, std::move(big_params));
  }
  }
}


void IsoManager::TerminateBig(uint8_t big_id, uint8_t reason) {
void IsoManager::TerminateBig(uint8_t big_id, uint8_t reason) {
  if (pimpl_->IsRunning()) {
  if (pimpl_->IsRunning()) {
+46 −0
Original line number Original line Diff line number Diff line
@@ -2335,6 +2335,52 @@ TEST_F(IsoManagerDeathTestNoCleanup, HandleLateArivingEventHandleHciEvent) {
  IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT, buf.data(), buf.size());
  IsoManager::GetInstance()->HandleHciEvent(HCI_BLE_TERM_BIG_CPL_EVT, buf.data(), buf.size());
}
}


/* This test makes sure we do not crash when calling into a non-started Iso Manager
 */
TEST_F(IsoManagerDeathTestNoCleanup, HandleApiCallsWhenStopped) {
  IsoManager::GetInstance()->Stop();
  IsoManager::GetInstance()->RegisterCigCallbacks(cig_callbacks_.get());
  IsoManager::GetInstance()->RegisterBigCallbacks(big_callbacks_.get());
  IsoManager::GetInstance()->RegisterOnIsoTrafficActiveCallback(iso_active_callback);

  IsoManager::GetInstance()->CreateCig(volatile_test_cig_create_cmpl_evt_.cig_id,
                                       kDefaultCigParams);
  IsoManager::GetInstance()->ReconfigureCig(volatile_test_cig_create_cmpl_evt_.cig_id,
                                            kDefaultCigParams);

  bluetooth::hci::iso_manager::cis_establish_params params;
  for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
    params.conn_pairs.push_back({handle, 1});
  }
  IsoManager::GetInstance()->EstablishCis(params);

  bluetooth::hci::iso_manager::iso_data_path_params path_params = kDefaultIsoDataPathParams;
  for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
    path_params.data_path_dir = bluetooth::hci::iso_manager::kIsoDataPathDirectionIn;
    IsoManager::GetInstance()->SetupIsoDataPath(handle, path_params);

    path_params.data_path_dir = bluetooth::hci::iso_manager::kRemoveIsoDataPathDirectionInput;
    IsoManager::GetInstance()->RemoveIsoDataPath(handle, path_params.data_path_dir);
  }

  auto handle = volatile_test_cig_create_cmpl_evt_.conn_handles[0];
  IsoManager::GetInstance()->ReadIsoLinkQuality(handle);

  std::vector<uint8_t> data_vec(108, 0);
  IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(), data_vec.size());
  IsoManager::GetInstance()->SendIsoData(handle, data_vec.data(), data_vec.size());

  for (auto& handle : volatile_test_cig_create_cmpl_evt_.conn_handles) {
    IsoManager::GetInstance()->IsoManager::GetInstance()->DisconnectCis(handle, 0x16);
  }

  IsoManager::GetInstance()->RemoveCig(volatile_test_cig_create_cmpl_evt_.cig_id);
  (void)IsoManager::GetInstance()->GetNumberOfActiveIso();

  IsoManager::GetInstance()->CreateBig(volatile_test_big_params_evt_.big_id, kDefaultBigParams);
  IsoManager::GetInstance()->TerminateBig(volatile_test_big_params_evt_.big_id, 0x16);
}

TEST_F(IsoManagerTest, HandleIsoDataSameSeqNb) {
TEST_F(IsoManagerTest, HandleIsoDataSameSeqNb) {
  IsoManager::GetInstance()->CreateCig(volatile_test_cig_create_cmpl_evt_.cig_id,
  IsoManager::GetInstance()->CreateCig(volatile_test_cig_create_cmpl_evt_.cig_id,
                                       kDefaultCigParams);
                                       kDefaultCigParams);