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