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

Commit 1adfae93 authored by xiaoshun.xu's avatar xiaoshun.xu Committed by Gregory Montoir
Browse files

Fix VTS Fuzz issue

[Description]
Fix is designed to fix VTS Fuzz issue,
1. Add null pointer check in bluetooth_hci.cc and
vendor_interface.cc
2. send should return if open is not done;
3. add lock in callback and set new callback

Bug: 247053367
Test:
1. Build Pass
2. Test VTS fuzz pass

Change-Id: I78da5aeb82f9f78b2b4a156196199183ce0dd8f2
parent 449d7b0f
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@ static const uint8_t HCI_DATA_TYPE_SCO = 3;

class BluetoothDeathRecipient : public hidl_death_recipient {
 public:
  BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
  BluetoothDeathRecipient(const sp<IBluetoothHci> hci)
    : mHci(hci), has_died_(false) {}

  virtual void serviceDied(
      uint64_t /*cookie*/,
@@ -51,7 +52,7 @@ class BluetoothDeathRecipient : public hidl_death_recipient {
};

BluetoothHci::BluetoothHci()
    : death_recipient_(new BluetoothDeathRecipient(this)) {}
    : death_recipient_(new BluetoothDeathRecipient(this)) {bt_enabled = 0;}

Return<void> BluetoothHci::initialize(
    const ::android::sp<IBluetoothHciCallbacks>& cb) {
@@ -61,8 +62,19 @@ Return<void> BluetoothHci::initialize(
    return Void();
  }

  if (bt_enabled == 1) {
    ALOGE("initialize was called!");
    return Void();
  }
  bt_enabled = 1;
  death_recipient_->setHasDied(false);
  cb->linkToDeath(death_recipient_, 0);
  unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
    if (death_recipient->getHasDied())
      ALOGI("Skipping unlink call, service died.");
    else
      cb->unlinkToDeath(death_recipient);
  };

  bool rc = VendorInterface::Initialize(
      [cb](bool status) {
@@ -112,6 +124,12 @@ Return<void> BluetoothHci::initialize(

Return<void> BluetoothHci::close() {
  ALOGI("BluetoothHci::close()");

  if (bt_enabled != 1) {
    ALOGE("should initialize first!");
    return Void();
  }
  bt_enabled = 0;
  unlink_cb_(death_recipient_);
  VendorInterface::Shutdown();
  return Void();
@@ -134,6 +152,11 @@ Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {

void BluetoothHci::sendDataToController(const uint8_t type,
                                        const hidl_vec<uint8_t>& data) {
  if (bt_enabled != 1) {
    ALOGE("should initialize first!");
    return;
  }

  VendorInterface::get()->Send(type, data.data(), data.size());
}

+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ class BluetoothHci : public IBluetoothHci {
  void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data);
  ::android::sp<BluetoothDeathRecipient> death_recipient_;
  std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_;
  int bt_enabled;
};

extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
+179 −113
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ static const char* VENDOR_LIBRARY_SYMBOL_NAME =
    "BLUETOOTH_VENDOR_LIB_INTERFACE";

static const int INVALID_FD = -1;
std::mutex vendor_mutex_;
std::mutex initcb_mutex_;

namespace {

@@ -47,13 +49,25 @@ struct {
  uint16_t opcode;
} internal_command;

enum {
  VENDOR_STATE_INIT = 1,
  VENDOR_STATE_OPENING,	/* during opening */
  VENDOR_STATE_OPENED,	/* open in fops_open */
  VENDOR_STATE_CLOSING,	/* during closing */
  VENDOR_STATE_CLOSED,	/* closed */

  VENDOR_STATE_MSG_NUM
} ;

uint8_t vstate = VENDOR_STATE_INIT;

// True when LPM is not enabled yet or wake is not asserted.
bool lpm_wake_deasserted;
uint32_t lpm_timeout_ms;
bool recent_activity_flag;

VendorInterface* g_vendor_interface = nullptr;
std::mutex wakeup_mutex_;
static VendorInterface vendor_interface;

HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
  size_t packet_size = data.size() + sizeof(HC_BT_HDR);
@@ -167,11 +181,8 @@ bool VendorInterface::Initialize(
    InitializeCompleteCallback initialize_complete_cb,
    PacketReadCallback event_cb, PacketReadCallback acl_cb,
    PacketReadCallback sco_cb, PacketReadCallback iso_cb) {
  if (g_vendor_interface) {
    ALOGE("%s: No previous Shutdown()?", __func__);
    return false;
  }
  g_vendor_interface = new VendorInterface();
  ALOGI("%s: VendorInterface::Initialize", __func__);
  g_vendor_interface = &vendor_interface;
  return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
                                  sco_cb, iso_cb);
}
@@ -179,9 +190,8 @@ bool VendorInterface::Initialize(
void VendorInterface::Shutdown() {
  LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
                      __func__);
  ALOGI("%s: VendorInterface::Shutdown", __func__);
  g_vendor_interface->Close();
  delete g_vendor_interface;
  g_vendor_interface = nullptr;
}

VendorInterface* VendorInterface::get() { return g_vendor_interface; }
@@ -191,8 +201,23 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
                           PacketReadCallback acl_cb,
                           PacketReadCallback sco_cb,
                           PacketReadCallback iso_cb) {
  initialize_complete_cb_ = initialize_complete_cb;
  {
    std::unique_lock<std::mutex> guard(vendor_mutex_);
    if (vstate == VENDOR_STATE_OPENED) {
      ALOGW("VendorInterface opened!");
      return true;
    }

    if ((vstate == VENDOR_STATE_CLOSING) ||
        (vstate == VENDOR_STATE_OPENING)) {
      ALOGW("VendorInterface open/close is on-going !");
      return true;
    }

    vstate = VENDOR_STATE_OPENING;
    ALOGI("%s: VendorInterface::Open", __func__);

    initialize_complete_cb_ = initialize_complete_cb;
    // Initialize vendor interface

    lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
@@ -212,9 +237,10 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,

  // Get the local BD address

  uint8_t local_bda[BluetoothAddress::kBytes];
    uint8_t local_bda[BluetoothAddress::kBytes] = {0, 0, 0, 0, 0, 0};
    if (!BluetoothAddress::get_local_address(local_bda)) {
    LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
      // BT driver will get BD address from NVRAM for MTK solution
      ALOGW("%s: No pre-set Bluetooth Address!", __func__);
    }
    int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
    if (status) {
@@ -263,7 +289,8 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
      fd_watcher_.WatchFdForNonBlockingReads(
          fd_list[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); });
      fd_watcher_.WatchFdForNonBlockingReads(
        fd_list[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
          fd_list[CH_ACL_IN],
          [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); });
      hci_ = mct_hci;
    }

@@ -274,19 +301,33 @@ bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
    firmware_startup_timer_ = new FirmwareStartupTimer();
    lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);

    vstate = VENDOR_STATE_OPENED;
    ALOGI("%s: VendorInterface::Open done!!!", __func__);
  }  // vendor_mutex_ done
  return true;
}

void VendorInterface::Close() {
  // These callbacks may send HCI events (vendor-dependent), so make sure to
  // StopWatching the file descriptor after this.

  if (vstate != VENDOR_STATE_OPENED) {
    ALOGW("VendorInterface is not allow close(%d)", vstate);
    return;
  }
  vstate = VENDOR_STATE_CLOSING;
  ALOGI("%s: VendorInterface::Close", __func__);

  if (lib_interface_ != nullptr) {
    lib_interface_->cleanup();
    bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
    lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
  }

  fd_watcher_.StopWatchingFileDescriptors();
  {
    std::unique_lock<std::mutex> guard(vendor_mutex_);

    fd_watcher_.StopWatchingFileDescriptors();
    if (hci_ != nullptr) {
      delete hci_;
      hci_ = nullptr;
@@ -298,7 +339,6 @@ void VendorInterface::Close() {
      int power_state = BT_VND_PWR_OFF;
      lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);

    lib_interface_->cleanup();
      lib_interface_ = nullptr;
    }

@@ -311,12 +351,26 @@ void VendorInterface::Close() {
      delete firmware_startup_timer_;
      firmware_startup_timer_ = nullptr;
    }
    vstate = VENDOR_STATE_CLOSED;
  }  // vendor_mutex_ done
  ALOGI("%s: VendorInterface::Close done!!!", __func__);
}

size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
  std::unique_lock<std::mutex> lock(wakeup_mutex_);
  recent_activity_flag = true;
  {
    std::unique_lock<std::mutex> guard(vendor_mutex_);

    if (vstate != VENDOR_STATE_OPENED) {
      ALOGW("VendorInterface is not open yet(%d)!", vstate);
      return 0;
    }
    ALOGI("%s: VendorInterface::Send", __func__);

    if (lib_interface_ == nullptr) {
      ALOGE("lib_interface_ is null");
      return 0;
    }
    recent_activity_flag = true;
    if (lpm_wake_deasserted == true) {
      // Restart the timer.
      fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
@@ -328,7 +382,8 @@ size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
      ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
    }

  return hci_->Send(type, data, length);
    return hci_ ? hci_->Send(type, data, length) : 0;
  }  // vendor_mutex_ done
}

void VendorInterface::OnFirmwareConfigured(uint8_t result) {
@@ -339,11 +394,17 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) {
    firmware_startup_timer_ = nullptr;
  }

  {
    std::unique_lock<std::mutex> guard(initcb_mutex_);
    ALOGD("%s OnFirmwareConfigured get lock", __func__);
    if (initialize_complete_cb_ != nullptr) {
      LOG_ALWAYS_FATAL_IF((result != 0),
          "%s: Failed to init firmware!", __func__);
      initialize_complete_cb_(result == 0);
    initialize_complete_cb_ = nullptr;
    }
  }  // initcb_mutex_ done

  if (lib_interface_ != nullptr) {
    lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
    ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);

@@ -354,10 +415,15 @@ void VendorInterface::OnFirmwareConfigured(uint8_t result) {
    fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
                                 [this]() { OnTimeout(); });
  }
  else {
    ALOGE("lib_interface_ is null");
  }

  initialize_complete_cb_ = nullptr;
}

void VendorInterface::OnTimeout() {
  ALOGV("%s", __func__);
  std::unique_lock<std::mutex> lock(wakeup_mutex_);
  if (recent_activity_flag == false) {
    lpm_wake_deasserted = true;
    bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
+3 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@
#include "bt_vendor_lib.h"
#include "hci_protocol.h"

extern std::mutex initcb_mutex_;

namespace android {
namespace hardware {
namespace bluetooth {
@@ -45,10 +47,9 @@ class VendorInterface {
  size_t Send(uint8_t type, const uint8_t* data, size_t length);

  void OnFirmwareConfigured(uint8_t result);

 private:
  virtual ~VendorInterface() = default;

 private:
  bool Open(InitializeCompleteCallback initialize_complete_cb,
            PacketReadCallback event_cb, PacketReadCallback acl_cb,
            PacketReadCallback sco_cb, PacketReadCallback iso_cb);