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

Commit 6ac26a6e authored by Gurpreet Ghai's avatar Gurpreet Ghai Committed by Myles Watson
Browse files

BT: Use static lock to avoid race while cleanup

Problem:
The functions protected by mutex lock are called after cleanup
during shutdown. During this race condition, the structure set does not
exist and cause crash.

Steps:
Bluetooth on/off automation

Failure:
Bluetooth process crashes

RootCause:
Mutex is accessed after it is destroyed because of other thread calling
the function.

Fix:
Changed mutex lock to static type so that it exist and protect
the set structure even after cleanup.

Test: manual

Bug: 66921327

Change-Id: I8d1f5d5d607100ab73aec722a27688dae45cc323
parent e20fa6d4
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -27,13 +27,14 @@
#include "bt_common.h"
#include "btif_uid.h"

static std::mutex set_lock;

typedef struct uid_set_node_t {
  struct uid_set_node_t* next;
  bt_uid_traffic_t data;
} uid_set_node_t;

typedef struct uid_set_t {
  std::mutex lock;
  uid_set_node_t* head;
} uid_set_t;

@@ -43,7 +44,7 @@ uid_set_t* uid_set_create(void) {
}

void uid_set_destroy(uid_set_t* set) {
  std::unique_lock<std::mutex> lock(set->lock);
  std::unique_lock<std::mutex> guard(set_lock);
  uid_set_node_t* node = set->head;
  while (node) {
    uid_set_node_t* temp = node;
@@ -74,7 +75,7 @@ static uid_set_node_t* uid_set_find_or_create_node(uid_set_t* set,
void uid_set_add_tx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
  if (app_uid == -1 || bytes == 0) return;

  std::unique_lock<std::mutex> lock(set->lock);
  std::unique_lock<std::mutex> guard(set_lock);
  uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid);
  node->data.tx_bytes += bytes;
}
@@ -82,13 +83,13 @@ void uid_set_add_tx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
void uid_set_add_rx(uid_set_t* set, int32_t app_uid, uint64_t bytes) {
  if (app_uid == -1 || bytes == 0) return;

  std::unique_lock<std::mutex> lock(set->lock);
  std::unique_lock<std::mutex> guard(set_lock);
  uid_set_node_t* node = uid_set_find_or_create_node(set, app_uid);
  node->data.rx_bytes += bytes;
}

bt_uid_traffic_t* uid_set_read_and_clear(uid_set_t* set) {
  std::unique_lock<std::mutex> lock(set->lock);
  std::unique_lock<std::mutex> guard(set_lock);

  // Find the length
  size_t len = 0;