mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
fix(bt/bluedroid): fixed heap corruption when deinit SPP during SDP discovery
bta_jv_disable() reset the control block and let BTA_JvFree() release p_sdp_db/p_sdp_raw_data while an SDP service search could still be in progress. Late SDP responses were then parsed into the freed discovery database and corrupted the heap, so the crash surfaced much later in an unrelated malloc(), inside TLSF remove_free_block(). Cancel the search first. SDP_CancelServiceSearch() moves the connection control block to SDP_DISC_WAIT_CANCEL, and sdp_disc_server_rsp() matches none of its PDU cases in that state, so a late response is rejected instead of being written into the database. Reachable from both esp_spp_deinit() and esp_bt_l2cap_deinit(), e.g. when an application deinitializes SPP before ESP_SPP_DISCOVERY_COMP_EVT arrives.
This commit is contained in:
@@ -754,6 +754,15 @@ void bta_jv_disable (tBTA_JV_MSG *p_data)
|
||||
tBTA_JV_STATUS evt_data;
|
||||
evt_data = BTA_JV_SUCCESS;
|
||||
|
||||
/* An SDP search still in progress keeps writing into p_bta_jv_cfg->p_sdp_db,
|
||||
* which BTA_JvFree() releases once BTA_JV_DISABLE_EVT is handled. Cancel it
|
||||
* first: the connection control block then rejects any late response instead
|
||||
* of parsing it into freed memory. */
|
||||
if (bta_jv_cb.sdp_active != BTA_JV_SDP_ACT_NONE) {
|
||||
APPL_TRACE_WARNING("%s: SDP discovery active, cancelling it", __func__);
|
||||
SDP_CancelServiceSearch(p_bta_jv_cfg->p_sdp_db);
|
||||
}
|
||||
|
||||
// clear all the pm_cb slots
|
||||
for (int i = 0; i < BTA_JV_PM_MAX_NUM; i++) {
|
||||
if (bta_jv_cb.pm_cb[i].state != BTA_JV_PM_FREE_ST) {
|
||||
|
||||
Reference in New Issue
Block a user