mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'fix/fix_blufi_memory_copy_len_error_v6.0' into 'release/v6.0'
fix(ble): Fix blufi fragment reassembly bounds and buffer overflows (6.0) See merge request espressif/esp-idf!48268
This commit is contained in:
@@ -68,7 +68,9 @@ bool hci_host_check_send_available(void)
|
||||
void hci_host_send_packet(uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
bt_hci_log_record_hci_data(data[0], &data[1], len - 1);
|
||||
if (data != NULL && len > 1) {
|
||||
bt_hci_log_record_hci_data(data[0], &data[1], (uint16_t)(len - 1));
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
|
||||
ble_log_spi_out_hci_write(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len);
|
||||
|
||||
@@ -227,7 +227,9 @@ esp_err_t esp_bluedroid_init_with_cfg(esp_bluedroid_config_t *cfg)
|
||||
}
|
||||
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
bt_hci_log_init();
|
||||
if (bt_hci_log_init() != ESP_OK) {
|
||||
LOG_WARN("HCI log facility unavailable, continuing without HCI log\n");
|
||||
}
|
||||
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
|
||||
s_bt_host_state = ESP_BLUEDROID_STATUS_INITIALIZED;
|
||||
|
||||
@@ -92,7 +92,7 @@ bool btc_config_init(void)
|
||||
|
||||
config = config_new(CONFIG_FILE_PATH);
|
||||
if (!config) {
|
||||
BTC_TRACE_WARNING("%s unable to load config file; starting unconfigured.\n", __func__);
|
||||
BTC_TRACE_WARNING("%s unable to load/parse config; starting unconfigured without overwriting NVS.\n", __func__);
|
||||
config = config_new_empty();
|
||||
if (!config) {
|
||||
BTC_TRACE_ERROR("%s unable to allocate a config object.\n", __func__);
|
||||
@@ -345,14 +345,17 @@ int btc_config_clear(void)
|
||||
{
|
||||
assert(config != NULL);
|
||||
|
||||
config_free(config);
|
||||
btc_config_lock();
|
||||
|
||||
config_free(config);
|
||||
config = config_new_empty();
|
||||
if (config == NULL) {
|
||||
return false;
|
||||
btc_config_unlock();
|
||||
return -1;
|
||||
}
|
||||
int ret = config_save(config, CONFIG_FILE_PATH);
|
||||
return ret;
|
||||
bool ret = config_save(config, CONFIG_FILE_PATH);
|
||||
btc_config_unlock();
|
||||
return ret ? 0 : -1;
|
||||
}
|
||||
|
||||
void btc_config_lock(void)
|
||||
|
||||
@@ -593,7 +593,7 @@ static void btc_gap_ble_adv_pkt_handler(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
if (pkt_queue_length(p_env->adv_rpt_queue) != 0) {
|
||||
if (p_env->adv_rpt_ready && pkt_queue_length(p_env->adv_rpt_queue) != 0) {
|
||||
osi_thread_post_event(p_env->adv_rpt_ready, OSI_THREAD_MAX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
@@ -628,7 +628,9 @@ static void btc_process_adv_rpt_pkt(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_
|
||||
} while (0);
|
||||
|
||||
pkt_queue_enqueue(p_env->adv_rpt_queue, linked_pkt);
|
||||
osi_thread_post_event(p_env->adv_rpt_ready, OSI_THREAD_MAX_TIMEOUT);
|
||||
if (p_env->adv_rpt_ready) {
|
||||
osi_thread_post_event(p_env->adv_rpt_ready, OSI_THREAD_MAX_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_search_callback(tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH *p_data)
|
||||
@@ -3412,15 +3414,34 @@ void btc_gap_ble_deinit(void)
|
||||
#if (BLE_42_SCAN_EN == TRUE)
|
||||
btc_gap_ble_env_t *p_env = &btc_gap_ble_env;
|
||||
|
||||
osi_event_delete(p_env->adv_rpt_ready);
|
||||
struct osi_event *adv_evt = p_env->adv_rpt_ready;
|
||||
p_env->adv_rpt_ready = NULL;
|
||||
if (adv_evt) {
|
||||
osi_event_delete(adv_evt);
|
||||
}
|
||||
|
||||
pkt_queue_destroy(p_env->adv_rpt_queue, NULL);
|
||||
p_env->adv_rpt_queue = NULL;
|
||||
if (p_env->adv_rpt_queue) {
|
||||
pkt_queue_destroy(p_env->adv_rpt_queue, NULL);
|
||||
p_env->adv_rpt_queue = NULL;
|
||||
}
|
||||
#endif // #if (BLE_42_SCAN_EN == TRUE)
|
||||
#if (BLE_42_ADV_EN == TRUE)
|
||||
/* Under BTC_DYNAMIC_MEMORY, gl_bta_adv_data is a macro that dereferences
|
||||
* gl_bta_adv_data_ptr. Guard against the case where the pointer is NULL
|
||||
* (e.g. btc_init_mem() failed midway, or btc_deinit() is invoked twice)
|
||||
* to avoid &(*NULL) UB before reaching btc_cleanup_adv_data()'s NULL
|
||||
* check. */
|
||||
#if (BTC_DYNAMIC_MEMORY == TRUE)
|
||||
if (gl_bta_adv_data_ptr) {
|
||||
btc_cleanup_adv_data(&gl_bta_adv_data);
|
||||
}
|
||||
if (gl_bta_scan_rsp_data_ptr) {
|
||||
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
|
||||
}
|
||||
#else
|
||||
btc_cleanup_adv_data(&gl_bta_adv_data);
|
||||
btc_cleanup_adv_data(&gl_bta_scan_rsp_data);
|
||||
#endif // #if (BTC_DYNAMIC_MEMORY == TRUE)
|
||||
#endif // #if (BLE_42_ADV_EN == TRUE)
|
||||
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
|
||||
}
|
||||
|
||||
@@ -461,11 +461,10 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
|
||||
return;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
|
||||
alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
@@ -475,6 +474,7 @@ void btu_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_sec)
|
||||
p_tle->ticks = timeout_sec;
|
||||
p_tle->in_use = TRUE;
|
||||
osi_alarm_set(alarm, (period_ms_t)((period_ms_t)timeout_sec * 1000));
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -491,18 +491,21 @@ void btu_stop_timer(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
osi_mutex_lock(&btu_general_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (p_tle->in_use == FALSE) {
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
return;
|
||||
}
|
||||
p_tle->in_use = FALSE;
|
||||
|
||||
// Get the alarm for the timer list entry.
|
||||
osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -518,16 +521,18 @@ void btu_free_timer(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
p_tle->in_use = FALSE;
|
||||
|
||||
// Get the alarm for the timer list entry.
|
||||
osi_mutex_lock(&btu_general_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
osi_alarm_t *alarm = hash_map_get(btu_general_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
hash_map_erase(btu_general_alarm_hash_map, p_tle);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_general_alarm_lock);
|
||||
}
|
||||
|
||||
#if defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0)
|
||||
@@ -586,11 +591,10 @@ void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ti
|
||||
return;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
|
||||
alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
@@ -600,6 +604,7 @@ void btu_start_quick_timer(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_ti
|
||||
p_tle->in_use = TRUE;
|
||||
// The quick timer ticks are 100ms long.
|
||||
osi_alarm_set(alarm, (period_ms_t)(timeout_ticks * 100));
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -615,34 +620,39 @@ void btu_stop_quick_timer(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
osi_mutex_lock(&btu_l2cap_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (p_tle->in_use == FALSE) {
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
return;
|
||||
}
|
||||
p_tle->in_use = FALSE;
|
||||
|
||||
// Get the alarm for the timer list entry.
|
||||
osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
}
|
||||
|
||||
void btu_free_quick_timer(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
p_tle->in_use = FALSE;
|
||||
|
||||
// Get the alarm for the timer list entry.
|
||||
osi_mutex_lock(&btu_l2cap_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
osi_alarm_t *alarm = hash_map_get(btu_l2cap_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_DEBUG("%s Unable to find expected alarm in hashmap", __func__);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
hash_map_erase(btu_l2cap_alarm_hash_map, p_tle);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_l2cap_alarm_lock);
|
||||
}
|
||||
|
||||
#endif /* defined(QUICK_TIMER_TICKS_PER_SEC) && (QUICK_TIMER_TICKS_PER_SEC > 0) */
|
||||
@@ -682,11 +692,10 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_
|
||||
return;
|
||||
}
|
||||
}
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
|
||||
alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_ERROR("%s Unable to create alarm", __func__);
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
@@ -696,24 +705,28 @@ void btu_start_timer_oneshot(TIMER_LIST_ENT *p_tle, UINT16 type, UINT32 timeout_
|
||||
// NOTE: This value is in seconds but stored in a ticks field.
|
||||
p_tle->ticks = timeout_sec;
|
||||
osi_alarm_set(alarm, (period_ms_t)(timeout_sec * 1000));
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
}
|
||||
|
||||
void btu_stop_timer_oneshot(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
osi_mutex_lock(&btu_oneshot_alarm_lock, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (p_tle->in_use == FALSE) {
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
return;
|
||||
}
|
||||
p_tle->in_use = FALSE;
|
||||
|
||||
// Get the alarm for the timer list entry.
|
||||
osi_alarm_t *alarm = hash_map_get(btu_oneshot_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
HCI_TRACE_WARNING("%s Unable to find expected alarm in hashmap", __func__);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
p_tle->in_use = FALSE;
|
||||
osi_mutex_unlock(&btu_oneshot_alarm_lock);
|
||||
}
|
||||
|
||||
#if (defined(HCILP_INCLUDED) && HCILP_INCLUDED == TRUE)
|
||||
|
||||
Reference in New Issue
Block a user