diff --git a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c index ac810a94bc3..a833a5ac91a 100644 --- a/components/bt/host/bluedroid/btc/core/btc_ble_storage.c +++ b/components/bt/host/bluedroid/btc/core/btc_ble_storage.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -90,6 +90,17 @@ void btc_storage_save(void) } #if (BLE_INCLUDED == TRUE) +static bool btc_storage_is_all_zeros(const void *buf, size_t len) +{ + const uint8_t *p = (const uint8_t *)buf; + for (size_t i = 0; i < len; i++) { + if (p[i] != 0) { + return false; + } + } + return true; +} + static bt_status_t _btc_storage_add_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, char *key, uint8_t key_type, @@ -158,33 +169,48 @@ static bt_status_t _btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, { bdstr_t bdstr; bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - const char* name; + const char *name; + size_t expected_len; switch (key_type) { case BTM_LE_KEY_PENC: name = BTC_BLE_STORAGE_LE_KEY_PENC_STR; + expected_len = sizeof(tBTM_LE_PENC_KEYS); break; case BTM_LE_KEY_PID: name = BTC_BLE_STORAGE_LE_KEY_PID_STR; + expected_len = sizeof(tBTM_LE_PID_KEYS); break; case BTM_LE_KEY_PCSRK: name = BTC_BLE_STORAGE_LE_KEY_PCSRK_STR; + expected_len = sizeof(tBTM_LE_PCSRK_KEYS); break; case BTM_LE_KEY_LENC: name = BTC_BLE_STORAGE_LE_KEY_LENC_STR; + expected_len = sizeof(tBTM_LE_LENC_KEYS); break; case BTM_LE_KEY_LCSRK: name = BTC_BLE_STORAGE_LE_KEY_LCSRK_STR; + expected_len = sizeof(tBTM_LE_LCSRK_KEYS); break; case BTM_LE_KEY_LID: - name = BTC_BLE_STORAGE_LE_KEY_LID_STR; + /* LID is a flag-only key; no payload is persisted. */ + name = BTC_BLE_STORAGE_LE_KEY_LID_STR; + expected_len = 0; break; default: return BT_STATUS_FAIL; } - size_t length = key_length; - int ret = btc_config_get_bin(bdstr, name, (uint8_t *)key_value, &length); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; + if (key_length < 0 || (size_t)key_length < expected_len) { + return BT_STATUS_FAIL; + } + + size_t length = (size_t)key_length; + bool ret = btc_config_get_bin(bdstr, name, (uint8_t *)key_value, &length); + if (!ret || length != expected_len) { + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; } bt_status_t btc_storage_get_ble_bonding_key(bt_bdaddr_t *remote_bd_addr, @@ -237,17 +263,22 @@ static bt_status_t _btc_storage_remove_all_ble_keys(const char *name) void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del_pid_key) { bt_bdaddr_t bd_addr; - uint32_t device_type = 0; if (del_pid_key == NULL) { return; } + // Only use valid static address for de-duplication. + if (btc_storage_is_all_zeros(del_pid_key->static_addr, sizeof(del_pid_key->static_addr))) { + return; + } + btc_config_lock(); const btc_config_section_iter_t *iter = btc_config_section_begin(); while (iter != btc_config_section_end()) { + uint32_t device_type = 0; //store the next iter, if remove section, then will not loss the point const char *section = btc_config_section_name(iter); @@ -276,13 +307,19 @@ void btc_storage_remove_unused_sections(uint8_t *cur_addr, tBTM_LE_PID_KEYS *del char buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; - if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) { + size_t pid_len = sizeof(tBTM_LE_PID_KEYS); + bool pid_ok = btc_config_get_bin(section, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)buffer, &pid_len); + + if (pid_ok && pid_len >= sizeof(tBTM_LE_PID_KEYS)) { tBTM_LE_PID_KEYS *pid_key = (tBTM_LE_PID_KEYS *) buffer; iter = btc_config_section_next(iter); - if (memcmp(del_pid_key->static_addr, pid_key->static_addr, 6) == 0 && memcmp(cur_addr, bd_addr.address, 6) != 0 && del_pid_key->addr_type == pid_key->addr_type) { + if (del_pid_key->addr_type == pid_key->addr_type && + !btc_storage_is_all_zeros(pid_key->static_addr, sizeof(pid_key->static_addr)) && + memcmp(del_pid_key->static_addr, pid_key->static_addr, sizeof(pid_key->static_addr)) == 0 && + memcmp(cur_addr, bd_addr.address, sizeof(bd_addr.address)) != 0) { if (device_type == BT_DEVICE_TYPE_DUMO) { btc_config_set_int(section, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR); _btc_storage_remove_all_ble_keys(section); @@ -308,13 +345,13 @@ void btc_storage_delete_duplicate_ble_devices(void) char temp_buffer[sizeof(tBTM_LE_KEY_VALUE)] = {0}; tBTM_LE_PID_KEYS *pid_key; tBTM_LE_PID_KEYS *temp_pid_key; - uint32_t device_type = 0; bt_bdaddr_t temp_bd_addr; btc_config_lock(); for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) { + uint32_t device_type = 0; const char *name = btc_config_section_name(iter); if (!string_is_bdaddr(name) || @@ -324,27 +361,36 @@ void btc_storage_delete_duplicate_ble_devices(void) } string_to_bdaddr(name, &bd_addr); - if (_btc_storage_get_ble_bonding_key(&bd_addr, BTM_LE_KEY_PID, buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) + size_t pid_len = sizeof(tBTM_LE_PID_KEYS); + bool pid_ok = btc_config_get_bin(name, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)buffer, &pid_len); + if (pid_ok && pid_len >= sizeof(tBTM_LE_PID_KEYS)) { pid_key = (tBTM_LE_PID_KEYS *) buffer; + if (btc_storage_is_all_zeros(pid_key->static_addr, sizeof(pid_key->static_addr))) { + continue; + } const btc_config_section_iter_t *temp_iter = btc_config_section_next(iter); while (temp_iter != NULL) { + uint32_t temp_device_type = 0; const char *temp_name = btc_config_section_name(temp_iter); - if (!string_is_bdaddr(temp_name) || !btc_config_get_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || - ((device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { + if (!string_is_bdaddr(temp_name) || !btc_config_get_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&temp_device_type) || + ((temp_device_type & BT_DEVICE_TYPE_BLE) != BT_DEVICE_TYPE_BLE)) { temp_iter = btc_config_section_next(temp_iter); continue; } string_to_bdaddr(temp_name, &temp_bd_addr); - if (_btc_storage_get_ble_bonding_key(&temp_bd_addr, BTM_LE_KEY_PID, temp_buffer, sizeof(tBTM_LE_PID_KEYS)) == BT_STATUS_SUCCESS) + size_t temp_pid_len = sizeof(tBTM_LE_PID_KEYS); + bool temp_pid_ok = btc_config_get_bin(temp_name, BTC_BLE_STORAGE_LE_KEY_PID_STR, (uint8_t *)temp_buffer, &temp_pid_len); + if (temp_pid_ok && temp_pid_len >= sizeof(tBTM_LE_PID_KEYS)) { temp_pid_key = (tBTM_LE_PID_KEYS *) temp_buffer; - if (memcmp(pid_key->static_addr, temp_pid_key->static_addr, 6) == 0 && pid_key->addr_type == temp_pid_key->addr_type) { - const char *temp_name = btc_config_section_name(temp_iter); + if (pid_key->addr_type == temp_pid_key->addr_type && + !btc_storage_is_all_zeros(temp_pid_key->static_addr, sizeof(temp_pid_key->static_addr)) && + memcmp(pid_key->static_addr, temp_pid_key->static_addr, sizeof(pid_key->static_addr)) == 0) { temp_iter = btc_config_section_next(temp_iter); - if (device_type == BT_DEVICE_TYPE_DUMO) { + if (temp_device_type == BT_DEVICE_TYPE_DUMO) { btc_config_set_int(temp_name, BTC_BLE_STORAGE_DEV_TYPE_STR, BT_DEVICE_TYPE_BREDR); _btc_storage_remove_all_ble_keys(temp_name); } else { @@ -484,9 +530,11 @@ static bt_status_t _btc_storage_get_ble_local_key(uint8_t key_type, } size_t length = key_length; - int ret = btc_config_get_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (uint8_t *)key_value, &length); - - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; + bool ret = btc_config_get_bin(BTC_BLE_STORAGE_LOCAL_ADAPTER_STR, name, (uint8_t *)key_value, &length); + if (!ret || length != (size_t)key_length) { + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; } bt_status_t btc_storage_get_ble_local_key(uint8_t key_type, @@ -905,8 +953,8 @@ static void _btc_read_le_key(const uint8_t key_type, const size_t key_len, bt_bd } bt_status_t _btc_storage_in_fetch_bonded_ble_device(const char *remote_bd_addr, int add) { - uint32_t device_type; - int addr_type; + uint32_t device_type = 0; + int addr_type = BLE_ADDR_PUBLIC; bt_bdaddr_t bd_addr; BD_ADDR bta_bd_addr; bool device_added = false; @@ -1015,11 +1063,11 @@ bt_status_t btc_storage_get_bonded_ble_devices_list(esp_ble_bond_dev_t *bond_dev int btc_storage_get_num_ble_bond_devices(void) { int num_dev = 0; - uint32_t device_type = 0; btc_config_lock(); for (const btc_config_section_iter_t *iter = btc_config_section_begin(); iter != btc_config_section_end(); iter = btc_config_section_next(iter)) { + uint32_t device_type = 0; const char *name = btc_config_section_name(iter); if (!string_is_bdaddr(name) || !btc_config_get_int(name, BTC_BLE_STORAGE_DEV_TYPE_STR, (int *)&device_type) || @@ -1037,18 +1085,30 @@ int btc_storage_get_num_ble_bond_devices(void) bt_status_t btc_storage_get_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) { bdstr_t bdstr; - bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - int ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t *)&len); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; + bool ret; + size_t length = len; + + btc_config_lock(); + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); + ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, &length); + btc_config_unlock(); + + if (!ret || length != (size_t)len) { + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; } bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) { - int ret; + bool ret; bdstr_t bdstr; btc_config_lock(); bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR, value, (size_t)len); + if (ret) { + _btc_storage_save(); + } btc_config_unlock(); if (ret == false) { return BT_STATUS_FAIL; @@ -1060,18 +1120,33 @@ bt_status_t btc_storage_set_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr, uint8 bt_status_t btc_storage_get_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) { bdstr_t bdstr; - bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - int ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, (size_t *)&len); - return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL; + bool ret; + size_t length = len; + + btc_config_lock(); + bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); + ret = btc_config_get_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, &length); + btc_config_unlock(); + + if (!ret || length != (size_t)len) { + return BT_STATUS_FAIL; + } + return BT_STATUS_SUCCESS; } bt_status_t btc_storage_set_gatt_db_hash(bt_bdaddr_t *remote_bd_addr, uint8_t *value, int len) { - int ret; + bool ret; bdstr_t bdstr; + btc_config_lock(); bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr_t)); ret = btc_config_set_bin(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR, value, (size_t)len); + if (ret) { + _btc_storage_save(); + } + btc_config_unlock(); + if (ret == false) { return BT_STATUS_FAIL; } @@ -1084,9 +1159,11 @@ bt_status_t btc_storage_remove_gatt_cl_supp_feat(bt_bdaddr_t *remote_bd_addr) bool ret = true; bdstr_t bdstr; + btc_config_lock(); bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_GATT_CL_SUPP_FEAT_STR); + btc_config_unlock(); + if (ret == false) { return BT_STATUS_FAIL; } @@ -1099,9 +1176,11 @@ bt_status_t btc_storage_remove_gatt_db_hash(bt_bdaddr_t *remote_bd_addr) bool ret = true; bdstr_t bdstr; + btc_config_lock(); bdaddr_to_string(remote_bd_addr, bdstr, sizeof(bdstr)); - ret = btc_config_remove(bdstr, BTC_BLE_STORAGE_GATT_DB_HASH_STR); + btc_config_unlock(); + if (ret == false) { return BT_STATUS_FAIL; } diff --git a/components/bt/host/bluedroid/btc/core/btc_config.c b/components/bt/host/bluedroid/btc/core/btc_config.c index c55b80023d5..d78615a7dfd 100644 --- a/components/bt/host/bluedroid/btc/core/btc_config.c +++ b/components/bt/host/bluedroid/btc/core/btc_config.c @@ -277,6 +277,7 @@ bool btc_config_set_bin(const char *section, const char *key, const uint8_t *val config_set_string(config, section, key, str, false); + memset(str, 0, length * 2 + 1); osi_free(str); return true; } diff --git a/components/bt/host/bluedroid/btc/core/btc_dm.c b/components/bt/host/bluedroid/btc/core/btc_dm.c index 5f91481b6fb..416c9f4c2c3 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dm.c +++ b/components/bt/host/bluedroid/btc/core/btc_dm.c @@ -269,7 +269,7 @@ static void btc_dm_ble_auth_cmpl_evt (tBTA_DM_AUTH_CMPL *p_auth_cmpl) } #if BLE_SMP_BOND_NVS_FLASH - int addr_type; + int addr_type = BLE_ADDR_PUBLIC; if (btc_dm_cb.pairing_cb.ble.is_pid_key_rcvd) { // delete unused section in NVS