Merge branch 'bugfix/sdp_null_access' into 'master'

fix(bt/bluedroid): fixed SDP deinit race with pending callbacks

Closes BTQABR2023-737

See merge request espressif/esp-idf!48753
This commit is contained in:
Wang Meng Yang
2026-05-22 11:44:32 +08:00
2 changed files with 57 additions and 24 deletions

View File

@@ -524,6 +524,12 @@ void bta_sdp_search(tBTA_SDP_MSG *p_data)
APPL_TRACE_DEBUG("SDP control block handle is null\n");
return;
}
if (bta_sdp_cb.p_dm_cback == NULL) {
APPL_TRACE_DEBUG("SDP is not active\n");
return;
}
tBT_UUID *bta_sdp_search_uuid = osi_malloc(sizeof(tBT_UUID));
if (bta_sdp_search_uuid == NULL) {
APPL_TRACE_DEBUG("SDP search param malloc failed\n");
@@ -638,8 +644,17 @@ void bta_sdp_disable(tBTA_SDP_MSG *p_data)
APPL_TRACE_DEBUG("%s()\n", __func__);
tBTA_SDP bta_sdp;
bta_sdp.status = BTA_SDP_SUCCESS;
if (bta_sdp_cb.p_dm_cback) {
bta_sdp_cb.p_dm_cback(BTA_SDP_DISABLE_EVT, &bta_sdp, NULL);
tBTA_SDP_DM_CBACK *dm_cbk = bta_sdp_cb.p_dm_cback;
bta_sdp_cb.p_dm_cback = NULL;
if (p_bta_sdp_cfg->p_sdp_db && (bta_sdp_cb.sdp_active != BTA_SDP_ACTIVE_NONE)) {
if (!SDP_CancelServiceSearch(p_bta_sdp_cfg->p_sdp_db)) {
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
}
}
if (dm_cbk) {
dm_cbk(BTA_SDP_DISABLE_EVT, &bta_sdp, NULL);
}
}

View File

@@ -64,6 +64,18 @@ static void btc_sdp_cleanup(void)
if (sdp_local_param_ptr) {
#endif
if (sdp_local_param.sdp_slot_mutex) {
osi_mutex_lock(&sdp_local_param.sdp_slot_mutex, OSI_MUTEX_MAX_TIMEOUT);
for (int i = 0; i < SDP_MAX_RECORDS; i++) {
sdp_slot_t *slot = sdp_local_param.sdp_slots[i];
if (slot) {
if (slot->record_data) {
osi_free(slot->record_data);
}
osi_free(slot);
sdp_local_param.sdp_slots[i] = NULL;
}
}
osi_mutex_unlock(&sdp_local_param.sdp_slot_mutex);
osi_mutex_free(&sdp_local_param.sdp_slot_mutex);
sdp_local_param.sdp_slot_mutex = NULL;
}
@@ -1221,7 +1233,7 @@ static void btc_sdp_deinit(void)
BTA_SdpRemoveRecordByUser((void*)i);
}
}
BTA_SdpDisable();
ret = BTA_SdpDisable();
} while(0);
if (ret != ESP_SDP_SUCCESS) {
@@ -1407,34 +1419,40 @@ void btc_sdp_cb_handler(btc_msg_t *msg)
btc_sdp_cb_to_app(ESP_SDP_DEINIT_EVT, &param);
break;
case BTA_SDP_SEARCH_COMP_EVT:
// SDP search completed, now can be searched again
sdp_local_param.search_allowed = true;
if (is_sdp_init()) {
// SDP search completed, now can be searched again
sdp_local_param.search_allowed = true;
param.search.status = p_data->sdp_search_comp.status;
memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR));
bta_to_btc_uuid(&param.search.sdp_uuid, &p_data->sdp_search_comp.uuid);
param.search.record_count = p_data->sdp_search_comp.record_count;
param.search.records = (esp_bluetooth_sdp_record_t *)p_data->sdp_search_comp.records;
btc_sdp_cb_to_app(ESP_SDP_SEARCH_COMP_EVT, &param);
param.search.status = p_data->sdp_search_comp.status;
memcpy(param.search.remote_addr, p_data->sdp_search_comp.remote_addr, sizeof(BD_ADDR));
bta_to_btc_uuid(&param.search.sdp_uuid, &p_data->sdp_search_comp.uuid);
param.search.record_count = p_data->sdp_search_comp.record_count;
param.search.records = (esp_bluetooth_sdp_record_t *)p_data->sdp_search_comp.records;
btc_sdp_cb_to_app(ESP_SDP_SEARCH_COMP_EVT, &param);
}
break;
case BTA_SDP_CREATE_RECORD_USER_EVT:
param.create_record.status = p_data->sdp_create_record.status;
param.create_record.record_handle = p_data->sdp_create_record.handle;
btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param);
if (is_sdp_init()) {
param.create_record.status = p_data->sdp_create_record.status;
param.create_record.record_handle = p_data->sdp_create_record.handle;
btc_sdp_cb_to_app(ESP_SDP_CREATE_RECORD_COMP_EVT, &param);
}
break;
case BTA_SDP_REMOVE_RECORD_USER_EVT:
if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) {
int slot_id = get_sdp_slot_id_by_handle(p_data->sdp_remove_record.handle);
if (slot_id < 0) {
p_data->sdp_remove_record.status = ESP_SDP_NO_CREATE_RECORD;
} else {
free_sdp_slot(slot_id);
if (is_sdp_init()) {
if (p_data->sdp_remove_record.status == BTA_SDP_SUCCESS) {
int slot_id = get_sdp_slot_id_by_handle(p_data->sdp_remove_record.handle);
if (slot_id < 0) {
p_data->sdp_remove_record.status = ESP_SDP_NO_CREATE_RECORD;
} else {
free_sdp_slot(slot_id);
}
}
}
param.remove_record.status = p_data->sdp_remove_record.status;
param.remove_record.record_handle = p_data->sdp_remove_record.handle;
btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, &param);
param.remove_record.status = p_data->sdp_remove_record.status;
param.remove_record.record_handle = p_data->sdp_remove_record.handle;
btc_sdp_cb_to_app(ESP_SDP_REMOVE_RECORD_COMP_EVT, &param);
}
break;
default:
BTC_TRACE_DEBUG("%s: Unhandled event (%d)!", __func__, msg->act);