From 10008bcd7dba7592d7b5828ef1f06d3fcf36ada4 Mon Sep 17 00:00:00 2001
From: Hemant Gupta <hemantg@codeaurora.org>
Date: Fri, 9 Dec 2016 23:10:10 +0530
Subject: [PATCH] HID: Prevent crash by Cancelling SDP during cleanup

Usecase:
1) User tried to connect to HID Device.
2) SDP is internally performed by DUT. SDP is at stage,
   where L2CAP connection, configuration is done, and data
   fetch is ongoing.
3) BT was turned off from UI.
Observation:
BT crashed while accessing memory that was freed already because BT turn off,
caused ACL disconnection, leading to L2CAP disconnect indication in stack,
leading to sdp disconnect indication.
backtrace:
    #00 pc 000f98d4  /system/lib/hw/bluetooth.default.so (SDP_FindServiceUUIDInDb+51)
    #01 pc 000b5dbd  /system/lib/hw/bluetooth.default.so (hidh_search_callback+0x40)
    #02 pc 000f770b  /system/lib/hw/bluetooth.default.so (sdp_disconnect_ind+0x5e)
    #03 pc 00107a5f  /system/lib/hw/bluetooth.default.so (l2c_csm_execute+3446)
    #04 pc 001080e7  /system/lib/hw/bluetooth.default.so (l2c_link_hci_disc_comp+122)
    #05 pc 000fda81  /system/lib/hw/bluetooth.default.so (btu_hcif_process_event+588)
    #06 pc 000fec81  /system/lib/hw/bluetooth.default.so (btu_hci_msg_ready+96)
    #07 pc 00118191  /system/lib/hw/bluetooth.default.so
    #08 pc 0011917f  /system/lib/hw/bluetooth.default.so
    #09 pc 00041993  /system/lib/libc.so (_ZL15__pthread_startPv+30)
    #10 pc 000192b5  /system/lib/libc.so (__start_thread+6)
Register Dump
pid: 15740, tid: 15761, name: bluedroid wake/  >>> com.android.bluetooth <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x20000
    r0 815a5cac  r1 a1a2f370  r2 00000000  r3 85d4e541
    r4 00020000  r5 815a5cac  r6 a1a2f370  r7 b6d3ae40
    r8 00000000  r9 b6d3ae40  sl 00000002  fp 00000013
    ip a228c050  sp a1a2f360  lr a20eddc1  pc a21318d4  cpsr 200e0030
Rootcause
The above scenario could lead to crash we see as below, as bta_hh_cb.p_disc_db would be freed
during HID Host cleanup, and would be accessed via callback received for parsing SDP results on
SDP completion.
Fix:
While cleaning up HID Host, Cancel SDP search before freeing and resetting bta_hh_cb.p_disc_db.
This will internally send L2CAP disconnect request for SDP, and would lead to sdp_disconnect_cfm
call when L2CAP is disconnected, and would lead to call of hidh_search_callback with result code
as SDP_CANCEL.

Change-Id: I63563cb23dd69946f87a70cafa203c44edc9b753
---
 system/bta/hh/bta_hh_utils.cc | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/system/bta/hh/bta_hh_utils.cc b/system/bta/hh/bta_hh_utils.cc
index 28dd2be54f8..d0f60313345 100644
--- a/system/bta/hh/bta_hh_utils.cc
+++ b/system/bta/hh/bta_hh_utils.cc
@@ -429,7 +429,12 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status) {
     osi_free_and_reset(
         (void**)&bta_hh_cb.kdev[xx].dscp_info.descriptor.dsc_list);
   }
-  osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
+
+  if (bta_hh_cb.p_disc_db) {
+    /* Cancel SDP if it had been started. */
+    (void)SDP_CancelServiceSearch (bta_hh_cb.p_disc_db);
+    osi_free_and_reset((void**)&bta_hh_cb.p_disc_db);
+  }
 
   if (bta_hh_cb.p_cback) {
     (*bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH*)&status);
-- 
GitLab