From fd7e60b1fd42bfac85e1cf7babcae6323e314c02 Mon Sep 17 00:00:00 2001 From: Pavlin Radoslavov Date: Tue, 16 May 2017 18:50:43 -0700 Subject: [PATCH] Protect the message loop from accesses after HCI shutdown Bug: 38330724 Test: Manual: enable/disable Bluetooth Change-Id: Iaece4cd608c67b28b436ded9fcc51c0bf28f4098 (cherry picked from commit 7277f39540fefe551dc2120fc4db787a9ed57646) --- hci/src/hci_layer.cc | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/hci/src/hci_layer.cc b/hci/src/hci_layer.cc index cb6cd2922..f490a91a4 100644 --- a/hci/src/hci_layer.cc +++ b/hci/src/hci_layer.cc @@ -85,6 +85,7 @@ static const packet_fragmenter_t* packet_fragmenter; static future_t* startup_future; static thread_t* thread; // We own this +static std::mutex message_loop_mutex; static base::MessageLoop* message_loop_ = nullptr; static base::RunLoop* run_loop_ = nullptr; @@ -126,6 +127,7 @@ static const packet_fragmenter_callbacks_t packet_fragmenter_callbacks = { transmit_fragment, dispatch_reassembled, fragmenter_transmit_finished}; void initialization_complete() { + std::lock_guard lock(message_loop_mutex); message_loop_->task_runner()->PostTask( FROM_HERE, base::Bind(&event_finish_startup, nullptr)); } @@ -154,18 +156,23 @@ void sco_data_received(BT_HDR* packet) { static future_t* hci_module_shut_down(); void message_loop_run(UNUSED_ATTR void* context) { - message_loop_ = new base::MessageLoop(); - run_loop_ = new base::RunLoop(); + { + std::lock_guard lock(message_loop_mutex); + message_loop_ = new base::MessageLoop(); + run_loop_ = new base::RunLoop(); + } message_loop_->task_runner()->PostTask(FROM_HERE, base::Bind(&hci_initialize)); run_loop_->Run(); - delete message_loop_; - message_loop_ = nullptr; - - delete run_loop_; - run_loop_ = nullptr; + { + std::lock_guard lock(message_loop_mutex); + delete message_loop_; + message_loop_ = nullptr; + delete run_loop_; + run_loop_ = nullptr; + } } static future_t* hci_module_start_up(void) { @@ -246,7 +253,10 @@ static future_t* hci_module_shut_down() { startup_timer = NULL; } - message_loop_->task_runner()->PostTask(FROM_HERE, run_loop_->QuitClosure()); + { + std::lock_guard lock(message_loop_mutex); + message_loop_->task_runner()->PostTask(FROM_HERE, run_loop_->QuitClosure()); + } // Stop the thread to prevent Send() calls. if (thread) { @@ -355,8 +365,15 @@ static void startup_timer_expired(UNUSED_ATTR void* context) { static void enqueue_command(waiting_command_t* wait_entry) { base::Closure callback = base::Bind(&event_command_ready, wait_entry); - std::lock_guard lock(command_credits_mutex); + std::lock_guard command_credits_lock(command_credits_mutex); if (command_credits > 0) { + std::lock_guard message_loop_lock(message_loop_mutex); + if (message_loop_ == nullptr) { + // HCI Layer was shut down + buffer_allocator->free(wait_entry->command); + osi_free(wait_entry); + return; + } message_loop_->task_runner()->PostTask(FROM_HERE, std::move(callback)); command_credits--; } else { @@ -377,6 +394,12 @@ static void event_command_ready(waiting_command_t* wait_entry) { } static void enqueue_packet(void* packet) { + std::lock_guard lock(message_loop_mutex); + if (message_loop_ == nullptr) { + // HCI Layer was shut down + buffer_allocator->free(packet); + return; + } message_loop_->task_runner()->PostTask( FROM_HERE, base::Bind(&event_packet_ready, packet)); } @@ -439,8 +462,13 @@ static void command_timed_out(UNUSED_ATTR void* context) { // Event/packet receiving functions void process_command_credits(int credits) { - std::lock_guard lock(command_credits_mutex); + std::lock_guard command_credits_lock(command_credits_mutex); + std::lock_guard message_loop_lock(message_loop_mutex); + if (message_loop_ == nullptr) { + // HCI Layer was shut down + return; + } command_credits = credits; while (command_credits > 0 && command_queue.size() > 0) { message_loop_->task_runner()->PostTask(FROM_HERE, -- 2.11.0