mirror of
https://github.com/espressif/esp-idf.git
synced 2026-01-21 19:25:53 +00:00
Merge branch 'bugfix/fix_ble_security_issue_2025_v5.5' into 'release/v5.5'
Fix potential CVE-2024-0039 out-of-bounds write in attp_build_value_cmd (v5.5) See merge request espressif/esp-idf!43807
This commit is contained in:
@@ -111,6 +111,10 @@ esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (adv_params == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_START_ADV;
|
||||
@@ -171,6 +175,10 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (remote_device == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN;
|
||||
@@ -182,6 +190,9 @@ esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_
|
||||
|
||||
esp_err_t esp_ble_gap_addr_create_static(esp_bd_addr_t rand_addr)
|
||||
{
|
||||
if (rand_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
// Static device address: First two bits are '11', rest is random
|
||||
rand_addr[0] = 0xC0 | (esp_random() & 0x3F);
|
||||
for (int i = 1; i < 6; i++) {
|
||||
@@ -192,6 +203,9 @@ esp_err_t esp_ble_gap_addr_create_static(esp_bd_addr_t rand_addr)
|
||||
|
||||
esp_err_t esp_ble_gap_addr_create_nrpa(esp_bd_addr_t rand_addr)
|
||||
{
|
||||
if (rand_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
// Non-resolvable private address: First two bits are '00', rest is random
|
||||
rand_addr[0] = (esp_random() & 0x3F);
|
||||
for (int i = 1; i < 6; i++) {
|
||||
@@ -207,6 +221,10 @@ esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (rand_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_RAND_ADDRESS;
|
||||
@@ -239,7 +257,7 @@ esp_err_t esp_ble_gap_add_device_to_resolving_list(esp_bd_addr_t peer_addr, uint
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (addr_type > BLE_ADDR_TYPE_RANDOM ||!peer_addr || (addr_type && ((peer_addr[0] & 0xC0) != 0xC0))) {
|
||||
if (addr_type > BLE_ADDR_TYPE_RANDOM || !peer_addr || !peer_irk || (addr_type && ((peer_addr[0] & 0xC0) != 0xC0))) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -357,6 +375,10 @@ esp_err_t esp_ble_gap_set_prefer_conn_params(esp_bd_addr_t bd_addr,
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (ESP_BLE_IS_VALID_PARAM(min_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
|
||||
ESP_BLE_IS_VALID_PARAM(max_conn_int, ESP_BLE_CONN_INT_MIN, ESP_BLE_CONN_INT_MAX) &&
|
||||
ESP_BLE_IS_VALID_PARAM(supervision_tout, ESP_BLE_CONN_SUP_TOUT_MIN, ESP_BLE_CONN_SUP_TOUT_MAX) &&
|
||||
@@ -424,6 +446,9 @@ esp_err_t esp_ble_gap_get_local_used_addr(esp_bd_addr_t local_used_addr, uint8_t
|
||||
LOG_ERROR("%s, bluedroid status error", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (local_used_addr == NULL || addr_type == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!BTM_BleGetCurrentAddress(local_used_addr, addr_type)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -436,13 +461,6 @@ uint8_t *esp_ble_resolve_adv_data_by_type( uint8_t *adv_data, uint16_t adv_data_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) &&
|
||||
(type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) {
|
||||
LOG_ERROR("The advertising data type is not defined, type = %x", type);
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (adv_data_len == 0) {
|
||||
*length = 0;
|
||||
return NULL;
|
||||
@@ -495,6 +513,10 @@ esp_err_t esp_ble_gap_read_rssi(esp_bd_addr_t remote_addr)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (remote_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_READ_RSSI;
|
||||
@@ -645,6 +667,10 @@ esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_ac
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_SET_ENCRYPTION_EVT;
|
||||
@@ -662,6 +688,10 @@ esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_SECURITY_RSP_EVT;
|
||||
@@ -680,6 +710,10 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_PASSKEY_REPLY_EVT;
|
||||
@@ -698,6 +732,10 @@ esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_CONFIRM_REPLY_EVT;
|
||||
@@ -712,6 +750,11 @@ esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (bd_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT;
|
||||
@@ -757,6 +800,10 @@ esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (bd_addr == NULL || TK == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg = {0};
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
@@ -775,7 +822,7 @@ esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len)
|
||||
|
||||
esp_err_t esp_ble_sc_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t p_c[16], uint8_t p_r[16])
|
||||
{
|
||||
if (!p_c || !p_r) {
|
||||
if (!bd_addr || !p_c || !p_r) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@@ -836,6 +883,10 @@ esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (remote_device == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_DISCONNECT_EVT;
|
||||
@@ -864,6 +915,10 @@ esp_err_t esp_gap_ble_set_channels(esp_gap_ble_channels channels)
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (channels == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_SET_AFH_CHANNELS;
|
||||
|
||||
@@ -173,6 +173,10 @@ esp_err_t esp_ble_gattc_enh_open(esp_gatt_if_t gattc_if, esp_ble_gatt_creat_conn
|
||||
#if (BLE_42_FEATURE_SUPPORT == TRUE)
|
||||
esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct)
|
||||
{
|
||||
if (remote_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
|
||||
memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
||||
creat_conn_params.remote_addr_type = remote_addr_type;
|
||||
@@ -187,6 +191,10 @@ esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, e
|
||||
#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
esp_err_t esp_ble_gattc_aux_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, esp_ble_addr_type_t remote_addr_type, bool is_direct)
|
||||
{
|
||||
if (remote_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
|
||||
memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
||||
creat_conn_params.remote_addr_type = remote_addr_type;
|
||||
@@ -521,6 +529,10 @@ esp_err_t esp_ble_gattc_read_multiple(esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (read_multi == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
|
||||
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
|
||||
LOG_WARN("%s, The connection not created.", __func__);
|
||||
@@ -557,6 +569,10 @@ esp_err_t esp_ble_gattc_read_multiple_variable(esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (read_multi == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
|
||||
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
|
||||
LOG_WARN("%s, The connection not created.", __func__);
|
||||
@@ -810,6 +826,10 @@ esp_err_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (server_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (handle == 0) {
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
@@ -832,6 +852,10 @@ esp_err_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (server_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (handle == 0) {
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
@@ -852,6 +876,10 @@ esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (remote_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CACHE_REFRESH;
|
||||
@@ -867,6 +895,10 @@ esp_err_t esp_ble_gattc_cache_clean(esp_bd_addr_t remote_bda)
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (remote_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CACHE_CLEAN;
|
||||
@@ -882,6 +914,10 @@ esp_err_t esp_ble_gattc_cache_assoc(esp_gatt_if_t gattc_if, esp_bd_addr_t src_ad
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (src_addr == NULL || assoc_addr == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CACHE_ASSOC;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -78,6 +78,10 @@ esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (service_id == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CREATE_SERVICE;
|
||||
@@ -98,6 +102,10 @@ esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (gatts_attr_db == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (max_nb_attr > ESP_GATT_ATTR_HANDLE_MAX) {
|
||||
LOG_ERROR("The number of attribute should not be greater than CONFIG_BT_GATT_MAX_SR_ATTRIBUTES\n");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -143,6 +151,10 @@ esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (char_uuid == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* parameter validation check */
|
||||
status = esp_ble_gatts_add_char_desc_param_check(char_val, control);
|
||||
if (status != ESP_OK){
|
||||
@@ -183,6 +195,10 @@ esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (descr_uuid == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* parameter validation check */
|
||||
status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control);
|
||||
if (status != ESP_OK){
|
||||
@@ -344,6 +360,10 @@ esp_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *l
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (length == NULL || value == NULL) {
|
||||
return ESP_GATT_INVALID_PDU;
|
||||
}
|
||||
|
||||
if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
|
||||
*length = 0;
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
@@ -359,6 +379,10 @@ esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, b
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (remote_bda == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_OPEN;
|
||||
|
||||
@@ -241,7 +241,7 @@ void BTA_GATTS_AddCharacteristic (UINT16 service_id, const tBT_UUID * p_char_u
|
||||
p_buf->attr_val.attr_max_len = attr_val->attr_max_len;
|
||||
p_buf->attr_val.attr_val = (uint8_t *)osi_malloc(len);
|
||||
if(p_buf->attr_val.attr_val != NULL){
|
||||
memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
|
||||
memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -411,6 +411,14 @@ void BTA_GATTS_StopService(UINT16 service_id)
|
||||
void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len,
|
||||
UINT8 *p_data, BOOLEAN need_confirm)
|
||||
{
|
||||
|
||||
/* Validate data length against buffer size */
|
||||
if (data_len > BTA_GATT_MAX_ATTR_LEN) {
|
||||
APPL_TRACE_ERROR("GATT indication data too large: %u > %u",
|
||||
data_len, BTA_GATT_MAX_ATTR_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
tBTA_GATTS_API_INDICATION *p_buf;
|
||||
UINT16 len = sizeof(tBTA_GATTS_API_INDICATION);
|
||||
|
||||
|
||||
@@ -89,6 +89,20 @@ void BTA_HdDisable(void)
|
||||
******************************************************************************/
|
||||
extern void BTA_HdRegisterApp(tBTA_HD_APP_INFO *p_app_info, tBTA_HD_QOS_INFO *p_in_qos, tBTA_HD_QOS_INFO *p_out_qos)
|
||||
{
|
||||
|
||||
/* Validate descriptor length before copying */
|
||||
if (p_app_info->descriptor.dl_len > BTA_HD_APP_DESCRIPTOR_LEN) {
|
||||
APPL_TRACE_ERROR("HID descriptor too large: %u > %u",
|
||||
p_app_info->descriptor.dl_len, BTA_HD_APP_DESCRIPTOR_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate descriptor data pointer */
|
||||
if (p_app_info->descriptor.dl_len > 0 && p_app_info->descriptor.dsc_list == NULL) {
|
||||
APPL_TRACE_ERROR("HID descriptor data NULL but length > 0: %u", p_app_info->descriptor.dl_len);
|
||||
return;
|
||||
}
|
||||
|
||||
tBTA_HD_REGISTER_APP *p_buf;
|
||||
APPL_TRACE_API("%s", __func__);
|
||||
if ((p_buf = (tBTA_HD_REGISTER_APP *)osi_malloc(sizeof(tBTA_HD_REGISTER_APP))) != NULL) {
|
||||
@@ -158,6 +172,13 @@ extern void BTA_HdSendReport(tBTA_HD_REPORT *p_report)
|
||||
__func__, p_report->len, BTA_HD_REPORT_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate report data pointer */
|
||||
if (p_report->len > 0 && p_report->p_data == NULL) {
|
||||
APPL_TRACE_ERROR("HID report data pointer NULL but length > 0: %d", p_report->len);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p_buf = (tBTA_HD_SEND_REPORT *)osi_malloc(sizeof(tBTA_HD_SEND_REPORT))) != NULL) {
|
||||
p_buf->hdr.event = BTA_HD_API_SEND_REPORT_EVT;
|
||||
p_buf->use_intr = p_report->use_intr;
|
||||
|
||||
@@ -263,6 +263,18 @@ void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data, UINT8 *p_report,
|
||||
UINT16 xx, yy, key_idx = 0;
|
||||
UINT8 this_report[BTA_HH_MAX_RPT_CHARS];
|
||||
|
||||
/* Validate report length before processing */
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
APPL_TRACE_ERROR("HID report length exceeds maximum: %u > %u",
|
||||
report_len, BTA_HH_MAX_RPT_CHARS);
|
||||
return;
|
||||
}
|
||||
|
||||
if (report_len == 0 || p_report == NULL) {
|
||||
APPL_TRACE_ERROR("Invalid HID report data");
|
||||
return;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_keybd_rpt: (report=%p, report_len=%d) called",
|
||||
p_report, report_len);
|
||||
@@ -463,7 +475,7 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
|
||||
|
||||
if (bta_hh_cb.p_cback) {
|
||||
(*bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH*)&status);
|
||||
/* all connections are down, no waiting for diconnect */
|
||||
/* all connections are down, no waiting for disconnect */
|
||||
memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,9 +508,10 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
STREAM_TO_UINT8(length, stream);
|
||||
}
|
||||
|
||||
if ((length + hdr_size) != packet->len) {
|
||||
HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
|
||||
"pkt_len=%d", type, hdr_size, length, packet->len);
|
||||
// Prevents integer wrap-around when calculating (length + hdr_size).
|
||||
if (length != (packet->len - hdr_size)) {
|
||||
HCI_TRACE_ERROR("%s: SECURITY: parameter length (%d) exceeds packet bounds (%d)",
|
||||
__func__, length, packet->len - hdr_size);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -452,10 +452,12 @@ static bool filter_incoming_event(BT_HDR *packet)
|
||||
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
|
||||
STREAM_TO_UINT16(opcode, stream);
|
||||
wait_entry = get_waiting_command(opcode);
|
||||
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
|
||||
if (!wait_entry) {
|
||||
HCI_TRACE_WARNING("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
|
||||
} else if (metadata->command_complete_cb) {
|
||||
goto intercepted;
|
||||
}
|
||||
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
|
||||
if (metadata->command_complete_cb) {
|
||||
metadata->command_complete_cb(packet, metadata->context);
|
||||
#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
BlE_SYNC *sync_info = btsnd_hcic_ble_get_sync_info();
|
||||
@@ -482,10 +484,12 @@ static bool filter_incoming_event(BT_HDR *packet)
|
||||
// If a command generates a command status event, it won't be getting a command complete event
|
||||
|
||||
wait_entry = get_waiting_command(opcode);
|
||||
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
|
||||
if (!wait_entry) {
|
||||
HCI_TRACE_WARNING("%s command status event with no matching command. opcode: 0x%x", __func__, opcode);
|
||||
} else if (metadata->command_status_cb) {
|
||||
goto intercepted;
|
||||
}
|
||||
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
|
||||
if (metadata->command_status_cb) {
|
||||
metadata->command_status_cb(status, &metadata->command, metadata->context);
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ static void parse_ble_read_buffer_size_response_v2 (
|
||||
uint8_t *iso_pkt_num_ptr)
|
||||
{
|
||||
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SZIE_V2, 3 /* bytes after */);
|
||||
uint8_t *stream = read_command_complete_header(response, HCI_BLE_READ_BUFFER_SZIE_V2, 6 /* bytes after: 2+1+2+1 */);
|
||||
assert(stream != NULL);
|
||||
STREAM_TO_UINT16(*data_size_ptr, stream);
|
||||
STREAM_TO_UINT8(*acl_buffer_count_ptr, stream);
|
||||
|
||||
@@ -161,6 +161,13 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
osi_free(partial_packet);
|
||||
}
|
||||
|
||||
/* Check for integer overflow in length calculation */
|
||||
if (l2cap_length > (UINT16_MAX - L2CAP_HEADER_SIZE - HCI_ACL_PREAMBLE_SIZE)) {
|
||||
HCI_TRACE_ERROR("L2CAP length too large: %u", l2cap_length);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
|
||||
if (full_length <= packet->len) {
|
||||
if (full_length < packet->len) {
|
||||
@@ -200,6 +207,20 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
|
||||
packet->offset += HCI_ACL_PREAMBLE_SIZE; // skip ACL preamble
|
||||
packet->len -= HCI_ACL_PREAMBLE_SIZE;
|
||||
|
||||
// CVE-2020-0022 (BlueFrag) Fix: Prevent integer underflow
|
||||
if (partial_packet->offset > partial_packet->len) {
|
||||
HCI_TRACE_ERROR("%s offset exceeds expected length. Dropping packet.\n", __func__);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet->len > UINT16_MAX - partial_packet->offset) {
|
||||
HCI_TRACE_ERROR("%s: packet->len too large, would overflow. Dropping packet.\n", __func__);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t projected_offset = partial_packet->offset + packet->len;
|
||||
if (projected_offset > partial_packet->len) { // len stores the expected length
|
||||
HCI_TRACE_ERROR("%s got packet which would exceed expected length of %d. Truncating.\n", __func__, partial_packet->len);
|
||||
|
||||
@@ -1254,6 +1254,11 @@ void btm_ble_adv_set_terminated_evt(tBTM_BLE_ADV_TERMINAT *params)
|
||||
return;
|
||||
}
|
||||
|
||||
if (params->adv_handle >= MAX_BLE_ADV_INSTANCE) {
|
||||
BTM_TRACE_ERROR("%s, Invalid adv_handle %d, max is %d.", __func__, params->adv_handle, MAX_BLE_ADV_INSTANCE);
|
||||
return;
|
||||
}
|
||||
|
||||
// adv terminated due to connection, save the adv handle and connection handle
|
||||
if(params->status == 0x00) {
|
||||
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
|
||||
|
||||
@@ -3112,6 +3112,13 @@ void btm_ble_cache_adv_data(BD_ADDR bda, tBTM_INQ_RESULTS *p_cur, UINT8 data_len
|
||||
p_cur->scan_rsp_len = 0;
|
||||
}
|
||||
|
||||
/* Additional validation to prevent potential integer overflow */
|
||||
if (data_len > BTM_BLE_CACHE_ADV_DATA_MAX) {
|
||||
BTM_TRACE_ERROR("BLE advertising data length exceeds maximum: %u > %u",
|
||||
data_len, BTM_BLE_CACHE_ADV_DATA_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data_len > 0) {
|
||||
p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len];
|
||||
if((data_len + p_le_inq_cb->adv_len) <= BTM_BLE_CACHE_ADV_DATA_MAX) {
|
||||
|
||||
@@ -104,7 +104,7 @@ tGAP_CLCB *gap_ble_find_clcb_by_conn_id(UINT16 conn_id)
|
||||
}
|
||||
}
|
||||
|
||||
return p_clcb;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -126,10 +126,10 @@ tGAP_CLCB *gap_clcb_alloc (BD_ADDR bda)
|
||||
memset(p_clcb, 0, sizeof(tGAP_CLCB));
|
||||
p_clcb->in_use = TRUE;
|
||||
memcpy (p_clcb->bda, bda, BD_ADDR_LEN);
|
||||
break;
|
||||
return p_clcb;
|
||||
}
|
||||
}
|
||||
return p_clcb;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -665,6 +665,12 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
|
||||
switch (op_type) {
|
||||
case GATT_UUID_GAP_PREF_CONN_PARAM:
|
||||
GAP_TRACE_EVENT ("GATT_UUID_GAP_PREF_CONN_PARAM");
|
||||
/* Verify sufficient data length before reading connection parameters */
|
||||
if (p_data->att_value.len < 8) {
|
||||
GAP_TRACE_ERROR ("GATT_UUID_GAP_PREF_CONN_PARAM: insufficient data length %d", p_data->att_value.len);
|
||||
gap_ble_cl_op_cmpl(p_clcb, FALSE, 0, NULL);
|
||||
break;
|
||||
}
|
||||
/* Extract the peripheral preferred connection parameters and save them */
|
||||
|
||||
STREAM_TO_UINT16 (min, pp);
|
||||
@@ -679,7 +685,8 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
|
||||
|
||||
case GATT_UUID_GAP_DEVICE_NAME:
|
||||
GAP_TRACE_EVENT ("GATT_UUID_GAP_DEVICE_NAME\n");
|
||||
len = (UINT16)strlen((char *)pp);
|
||||
/* Use att_value.len instead of strlen to avoid reading beyond buffer */
|
||||
len = p_data->att_value.len;
|
||||
if (len > GAP_CHAR_DEV_NAME_SIZE) {
|
||||
len = GAP_CHAR_DEV_NAME_SIZE;
|
||||
}
|
||||
@@ -687,6 +694,12 @@ static void gap_ble_c_cmpl_cback (UINT16 conn_id, tGATTC_OPTYPE op, tGATT_STATUS
|
||||
break;
|
||||
|
||||
case GATT_UUID_GAP_CENTRAL_ADDR_RESOL:
|
||||
/* Verify sufficient data length */
|
||||
if (p_data->att_value.len < 1) {
|
||||
GAP_TRACE_ERROR ("GATT_UUID_GAP_CENTRAL_ADDR_RESOL: insufficient data length");
|
||||
gap_ble_cl_op_cmpl(p_clcb, FALSE, 0, NULL);
|
||||
break;
|
||||
}
|
||||
gap_ble_cl_op_cmpl(p_clcb, TRUE, 1, pp);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ UINT16 GAP_ConnOpen (const char *p_serv_name, UINT8 service_id, BOOLEAN is_serve
|
||||
|
||||
memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
|
||||
} else if (!is_server) {
|
||||
/* remore addr is not specified and is not a server -> bad */
|
||||
/* remote addr is not specified and is not a server -> bad */
|
||||
return (GAP_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
@@ -775,7 +775,9 @@ static void gap_checks_con_flags (tGAP_CCB *p_ccb)
|
||||
if ((p_ccb->con_flags & GAP_CCB_FLAGS_CONN_DONE) == GAP_CCB_FLAGS_CONN_DONE) {
|
||||
p_ccb->con_state = GAP_CCB_STATE_CONNECTED;
|
||||
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_OPENED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -933,7 +935,9 @@ static void gap_config_cfm (UINT16 l2cap_cid, tL2CAP_CFG_INFO *p_cfg)
|
||||
|
||||
gap_checks_con_flags (p_ccb);
|
||||
} else {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
|
||||
}
|
||||
gap_release_ccb (p_ccb);
|
||||
}
|
||||
}
|
||||
@@ -964,7 +968,9 @@ static void gap_disconnect_ind (UINT16 l2cap_cid, BOOLEAN ack_needed)
|
||||
L2CA_DISCONNECT_RSP (l2cap_cid);
|
||||
}
|
||||
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_CLOSED);
|
||||
}
|
||||
gap_release_ccb (p_ccb);
|
||||
}
|
||||
|
||||
@@ -997,7 +1003,9 @@ static void gap_data_ind (UINT16 l2cap_cid, BT_HDR *p_msg)
|
||||
p_ccb->rx_queue_size, p_msg->len);
|
||||
*/
|
||||
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, GAP_EVT_CONN_DATA_AVAIL);
|
||||
}
|
||||
} else {
|
||||
osi_free (p_msg);
|
||||
}
|
||||
@@ -1030,7 +1038,9 @@ static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
|
||||
p_ccb->is_congested = is_congested;
|
||||
|
||||
event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
|
||||
p_ccb->p_callback (p_ccb->gap_handle, event);
|
||||
if (p_ccb->p_callback) {
|
||||
p_ccb->p_callback (p_ccb->gap_handle, event);
|
||||
}
|
||||
|
||||
if (!is_congested) {
|
||||
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL) {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#define GATT_HDR_FIND_TYPE_VALUE_LEN 21
|
||||
#define GATT_OP_CODE_SIZE 1
|
||||
/**********************************************************************
|
||||
** ATT protocl message building utility *
|
||||
** ATT protocol message building utility *
|
||||
***********************************************************************/
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -285,57 +285,89 @@ BT_HDR *attp_build_opcode_cmd(UINT8 op_code)
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BT_HDR *attp_build_value_cmd (UINT16 payload_size, UINT8 op_code, UINT16 handle,
|
||||
UINT16 offset, UINT16 len, UINT8 *p_data)
|
||||
BT_HDR *attp_build_value_cmd(UINT16 payload_size, UINT8 op_code,
|
||||
UINT16 handle, UINT16 offset,
|
||||
UINT16 len, UINT8 *p_data)
|
||||
{
|
||||
BT_HDR *p_buf = NULL;
|
||||
UINT8 *p, *pp, pair_len, *p_pair_len;
|
||||
BT_HDR *p_buf = NULL;
|
||||
UINT8 *p = NULL, *pp = NULL, *p_pair_len = NULL;
|
||||
size_t pair_len = 0;
|
||||
size_t size_now = 1; /* track current buffer size including op_code */
|
||||
|
||||
if ((p_buf = (BT_HDR *)osi_malloc((UINT16)(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET))) != NULL) {
|
||||
p = pp = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
|
||||
#define CHECK_SIZE() \
|
||||
do { \
|
||||
if (size_now > payload_size) { \
|
||||
GATT_TRACE_ERROR("payload size too small"); \
|
||||
osi_free(p_buf); \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
UINT8_TO_STREAM (p, op_code);
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
p_buf->len = 1;
|
||||
/* allocate buffer with extra space for L2CAP offset */
|
||||
p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
|
||||
if (!p_buf) return NULL;
|
||||
|
||||
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
||||
p_pair_len = p;
|
||||
pair_len = len + 2;
|
||||
UINT8_TO_STREAM (p, pair_len);
|
||||
p_buf->len += 1;
|
||||
}
|
||||
if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ && op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) {
|
||||
UINT16_TO_STREAM (p, handle);
|
||||
p_buf->len += 2;
|
||||
p = pp = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
|
||||
|
||||
CHECK_SIZE();
|
||||
UINT8_TO_STREAM(p, op_code);
|
||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||
|
||||
/* handle Read By Type response: reserve space for pair_len */
|
||||
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
||||
p_pair_len = p++;
|
||||
pair_len = len + 2; /* handle(2 bytes) + value length */
|
||||
size_now += 1;
|
||||
CHECK_SIZE();
|
||||
/* pair_len will be backfilled after value is written */
|
||||
}
|
||||
|
||||
/* write handle if needed */
|
||||
if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ &&
|
||||
op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) {
|
||||
size_now += 2;
|
||||
CHECK_SIZE();
|
||||
UINT16_TO_STREAM(p, handle);
|
||||
}
|
||||
|
||||
/* write offset for prepare write requests */
|
||||
if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE) {
|
||||
size_now += 2;
|
||||
CHECK_SIZE();
|
||||
UINT16_TO_STREAM(p, offset);
|
||||
}
|
||||
|
||||
/* write value data, ensure it does not exceed payload_size */
|
||||
if (len > 0 && p_data != NULL) {
|
||||
if (payload_size - size_now < len) {
|
||||
len = payload_size - size_now;
|
||||
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
||||
pair_len = len + 2;
|
||||
}
|
||||
GATT_TRACE_WARNING("attribute value too long, truncated to %d", len);
|
||||
}
|
||||
|
||||
if (op_code == GATT_REQ_PREPARE_WRITE || op_code == GATT_RSP_PREPARE_WRITE ) {
|
||||
UINT16_TO_STREAM (p, offset);
|
||||
p_buf->len += 2;
|
||||
}
|
||||
size_now += len;
|
||||
CHECK_SIZE();
|
||||
|
||||
if(payload_size < GATT_DEF_BLE_MTU_SIZE || payload_size > GATT_MAX_MTU_SIZE) {
|
||||
GATT_TRACE_ERROR("invalid payload_size %d", payload_size);
|
||||
ARRAY_TO_STREAM(p, p_data, len);
|
||||
}
|
||||
|
||||
/* backfill pair_len for Read By Type response */
|
||||
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
||||
if (pair_len > UINT8_MAX) {
|
||||
GATT_TRACE_ERROR("pair_len > UINT8_MAX");
|
||||
osi_free(p_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len > 0 && p_data != NULL) {
|
||||
/* ensure data not exceed MTU size */
|
||||
if (payload_size - p_buf->len < len) {
|
||||
len = payload_size - p_buf->len;
|
||||
/* update handle value pair length */
|
||||
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
||||
*p_pair_len = (len + 2);
|
||||
}
|
||||
|
||||
GATT_TRACE_WARNING("attribute value too long, to be truncated to %d", len);
|
||||
}
|
||||
|
||||
ARRAY_TO_STREAM (p, p_data, len);
|
||||
p_buf->len += len;
|
||||
}
|
||||
*p_pair_len = (UINT8)pair_len;
|
||||
}
|
||||
|
||||
/* update buffer length */
|
||||
p_buf->len = (UINT16)size_now;
|
||||
|
||||
#undef CHECK_SIZE
|
||||
|
||||
return p_buf;
|
||||
}
|
||||
|
||||
@@ -462,7 +494,7 @@ BT_HDR *attp_build_sr_msg(tGATT_TCB *p_tcb, UINT8 op_code, tGATT_SR_MSG *p_msg)
|
||||
** Description This function sends the server response or indication message
|
||||
** to client.
|
||||
**
|
||||
** Parameter p_tcb: pointer to the connecton control block.
|
||||
** Parameter p_tcb: pointer to the connection control block.
|
||||
** p_msg: pointer to message parameters structure.
|
||||
**
|
||||
** Returns GATT_SUCCESS if successfully sent; otherwise error code.
|
||||
|
||||
@@ -66,7 +66,7 @@ static const UINT16 disc_type_to_uuid[GATT_DISC_MAX] = {
|
||||
0 /* no type filtering for DISC_CHAR_DSCPT */
|
||||
};
|
||||
|
||||
// Use for GATTC discover infomation print
|
||||
// Use for GATTC discover information print
|
||||
#define GATT_DISC_INFO(fmt, args...) {if (gatt_cb.auto_disc == FALSE) BT_PRINT_I("BT_GATT", fmt, ## args);}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -604,7 +604,7 @@ void gatt_process_prep_write_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op
|
||||
|
||||
GATT_TRACE_DEBUG("value resp op_code = %s len = %d", gatt_dbg_op_name(op_code), len);
|
||||
|
||||
if (len < GATT_PREP_WRITE_RSP_MIN_LEN) {
|
||||
if ((len < GATT_PREP_WRITE_RSP_MIN_LEN) || ((len - 4) > GATT_MAX_ATTR_LEN)) {
|
||||
GATT_TRACE_ERROR("illegal prepare write response length, discard");
|
||||
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
|
||||
return;
|
||||
@@ -701,7 +701,7 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code,
|
||||
}
|
||||
p_tcb->ind_count = 0;
|
||||
|
||||
/* should notify all registered client with the handle value notificaion/indication
|
||||
/* should notify all registered client with the handle value notification/indication
|
||||
Note: need to do the indication count and start timer first then do callback
|
||||
*/
|
||||
for (i = 0, p_reg = gatt_cb.cl_rcb; i < GATT_MAX_APPS; i++, p_reg++) {
|
||||
@@ -800,7 +800,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
||||
handle_len = 4;
|
||||
}
|
||||
|
||||
value_len -= handle_len; /* substract the handle pairs bytes */
|
||||
value_len -= handle_len; /* subtract the handle pairs bytes */
|
||||
len -= 1;
|
||||
|
||||
while (len >= (handle_len + value_len)) {
|
||||
@@ -887,7 +887,7 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
||||
gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p);
|
||||
}
|
||||
return;
|
||||
} else { /* discover characterisitic */
|
||||
} else { /* discover characteristic */
|
||||
STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
|
||||
STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
|
||||
if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle)) {
|
||||
@@ -979,7 +979,7 @@ void gatt_process_read_rsp(tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8 op_code,
|
||||
|
||||
if (len == (p_tcb->payload_size - 1) && /* full packet for read or read blob rsp */
|
||||
len + offset < GATT_MAX_ATTR_LEN) {
|
||||
GATT_TRACE_DEBUG("full pkt issue read blob for remianing bytes old offset=%d len=%d new offset=%d",
|
||||
GATT_TRACE_DEBUG("full pkt issue read blob for remaining bytes old offset=%d len=%d new offset=%d",
|
||||
offset, len, p_clcb->counter);
|
||||
gatt_act_read(p_clcb, p_clcb->counter);
|
||||
} else { /* end of request, send callback */
|
||||
|
||||
@@ -1039,20 +1039,23 @@ tGATT_STATUS gatts_write_attr_value_by_handle(tGATT_SVC_DB *p_db,
|
||||
return GATT_APP_RSP;
|
||||
}
|
||||
|
||||
if ((p_attr->p_value != NULL) &&
|
||||
(p_attr->p_value->attr_val.attr_max_len >= offset + len) &&
|
||||
p_attr->p_value->attr_val.attr_val != NULL) {
|
||||
memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
|
||||
p_attr->p_value->attr_val.attr_len = len + offset;
|
||||
return GATT_SUCCESS;
|
||||
} else if (p_attr->p_value && p_attr->p_value->attr_val.attr_max_len < offset + len){
|
||||
GATT_TRACE_DEBUG("Remote device try to write with a length larger then attribute's max length\n");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
} else if ((p_attr->p_value == NULL) || (p_attr->p_value->attr_val.attr_val == NULL)){
|
||||
if (p_attr->p_value == NULL || p_attr->p_value->attr_val.attr_val == NULL) {
|
||||
GATT_TRACE_ERROR("Error in %s, line=%d, %s should not be NULL here\n", __func__, __LINE__, \
|
||||
(p_attr->p_value == NULL) ? "p_value" : "attr_val.attr_val");
|
||||
return GATT_UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
/* Check for integer overflow: offset + len must not overflow UINT16
|
||||
* and must not exceed attr_max_len */
|
||||
if (offset > p_attr->p_value->attr_val.attr_max_len ||
|
||||
len > p_attr->p_value->attr_val.attr_max_len - offset) {
|
||||
GATT_TRACE_DEBUG("Remote device try to write with a length larger than attribute's max length\n");
|
||||
return GATT_INVALID_ATTR_LEN;
|
||||
}
|
||||
|
||||
memcpy(p_attr->p_value->attr_val.attr_val + offset, p_value, len);
|
||||
p_attr->p_value->attr_val.attr_len = offset + len;
|
||||
return GATT_SUCCESS;
|
||||
}
|
||||
|
||||
p_attr = (tGATT_ATTR16 *)p_attr->p_next;
|
||||
|
||||
@@ -197,7 +197,7 @@ enum {
|
||||
};
|
||||
typedef UINT8 tSMP_BR_STATE;
|
||||
|
||||
/* random and encrption activity state */
|
||||
/* random and encryption activity state */
|
||||
enum {
|
||||
SMP_GEN_COMPARE = 1,
|
||||
SMP_GEN_CONFIRM,
|
||||
@@ -363,6 +363,9 @@ extern tSMP_CB *smp_cb_ptr;
|
||||
/* Functions provided by att_main.c */
|
||||
extern void smp_init (void);
|
||||
|
||||
/* SMP command sizes per spec - defined in smp_utils.c */
|
||||
extern const UINT8 smp_cmd_size_per_spec[];
|
||||
|
||||
/* smp main */
|
||||
extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data);
|
||||
|
||||
|
||||
@@ -156,15 +156,31 @@ static void smp_connect_callback (UINT16 channel, BD_ADDR bd_addr, BOOLEAN conne
|
||||
static void smp_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
|
||||
{
|
||||
tSMP_CB *p_cb = &smp_cb;
|
||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
UINT8 cmd ;
|
||||
UINT8 *p;
|
||||
UINT8 cmd;
|
||||
SMP_TRACE_EVENT ("\nSMDBG l2c %s\n", __FUNCTION__);
|
||||
|
||||
/* Validate packet length before accessing data to prevent out-of-bounds read */
|
||||
if (p_buf->len < 1) {
|
||||
SMP_TRACE_WARNING ("Ignore empty SMP packet (len=%d)\n", p_buf->len);
|
||||
osi_free (p_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
||||
STREAM_TO_UINT8(cmd, p);
|
||||
|
||||
/* sanity check */
|
||||
if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) {
|
||||
SMP_TRACE_WARNING( "Ignore received command with RESERVED code 0x%02x\n", cmd);
|
||||
SMP_TRACE_WARNING ("Ignore received command with RESERVED code 0x%02x\n", cmd);
|
||||
osi_free (p_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate command length to prevent out-of-bounds read in handler functions */
|
||||
if (p_buf->len != smp_cmd_size_per_spec[cmd]) {
|
||||
SMP_TRACE_WARNING ("Ignore SMP cmd 0x%02x with invalid length %d (expected %d)\n",
|
||||
cmd, p_buf->len, smp_cmd_size_per_spec[cmd]);
|
||||
osi_free (p_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
#define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/)
|
||||
|
||||
/* SMP command sizes per spec */
|
||||
static const UINT8 smp_cmd_size_per_spec[] = {
|
||||
const UINT8 smp_cmd_size_per_spec[] = {
|
||||
0,
|
||||
SMP_PAIRING_REQ_SIZE, /* 0x01: pairing request */
|
||||
SMP_PAIRING_REQ_SIZE, /* 0x02: pairing response */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -126,14 +126,24 @@ void esp_receive_apple_data_source(uint8_t *message, uint16_t message_len)
|
||||
switch (Command_id)
|
||||
{
|
||||
case CommandIDGetNotificationAttributes: {
|
||||
// Security fix: Check minimum message length before accessing message[1..4]
|
||||
if (message_len < 5) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "Message too short for NotificationAttributes");
|
||||
break;
|
||||
}
|
||||
uint32_t NotificationUID = (message[1]) | (message[2]<< 8) | (message[3]<< 16) | (message[4] << 24);
|
||||
uint32_t remian_attr_len = message_len - 5;
|
||||
uint8_t *attrs = &message[5];
|
||||
ESP_LOGI(BLE_ANCS_TAG, "recevice Notification Attributes response Command_id %d NotificationUID %" PRIu32, Command_id, NotificationUID);
|
||||
while(remian_attr_len > 0) {
|
||||
// Security fix: Need at least 3 bytes for AttributeID(1) + len(2)
|
||||
if (remian_attr_len < 3) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "Incomplete attribute header");
|
||||
break;
|
||||
}
|
||||
uint8_t AttributeID = attrs[0];
|
||||
uint16_t len = attrs[1] | (attrs[2] << 8);
|
||||
if(len > (remian_attr_len -3)) {
|
||||
if(len > (remian_attr_len - 3)) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "data error");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -31,6 +31,8 @@
|
||||
#define ADV_CONFIG_FLAG (1 << 0)
|
||||
#define SCAN_RSP_CONFIG_FLAG (1 << 1)
|
||||
#define INVALID_HANDLE 0
|
||||
#define ANCS_CMD_BUFFER_MAX_SIZE 600
|
||||
|
||||
static uint8_t adv_config_done = 0;
|
||||
static bool get_service = false;
|
||||
static esp_gattc_char_elem_t *char_elem_result = NULL;
|
||||
@@ -168,15 +170,26 @@ esp_noti_attr_list_t p_attr[8] = {
|
||||
|
||||
void esp_get_notification_attributes(uint8_t *notificationUID, uint8_t num_attr, esp_noti_attr_list_t *p_attr)
|
||||
{
|
||||
uint8_t cmd[600] = {0};
|
||||
uint8_t cmd[ANCS_CMD_BUFFER_MAX_SIZE] = {0};
|
||||
uint32_t index = 0;
|
||||
|
||||
cmd[0] = CommandIDGetNotificationAttributes;
|
||||
index ++;
|
||||
memcpy(&cmd[index], notificationUID, ESP_NOTIFICATIONUID_LEN);
|
||||
index += ESP_NOTIFICATIONUID_LEN;
|
||||
while(num_attr > 0) {
|
||||
// Security fix: Check buffer boundary before writing
|
||||
if (index >= ANCS_CMD_BUFFER_MAX_SIZE) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "Command buffer overflow in get_notification_attributes");
|
||||
return;
|
||||
}
|
||||
cmd[index ++] = p_attr->noti_attribute_id;
|
||||
if (p_attr->attribute_len > 0) {
|
||||
// Need 2 more bytes for attribute_len
|
||||
if ((index + 2) > ANCS_CMD_BUFFER_MAX_SIZE) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "Command buffer overflow in get_notification_attributes");
|
||||
return;
|
||||
}
|
||||
cmd[index ++] = p_attr->attribute_len;
|
||||
cmd[index ++] = (p_attr->attribute_len << 8);
|
||||
}
|
||||
@@ -195,8 +208,15 @@ void esp_get_notification_attributes(uint8_t *notificationUID, uint8_t num_attr,
|
||||
|
||||
void esp_get_app_attributes(uint8_t *appidentifier, uint16_t appidentifier_len, uint8_t num_attr, uint8_t *p_app_attrs)
|
||||
{
|
||||
uint8_t buffer[600] = {0};
|
||||
uint8_t buffer[ANCS_CMD_BUFFER_MAX_SIZE] = {0};
|
||||
uint32_t index = 0;
|
||||
|
||||
// Security fix: Check buffer boundary before memcpy
|
||||
if ((1 + appidentifier_len + num_attr) > ANCS_CMD_BUFFER_MAX_SIZE) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "Buffer overflow in get_app_attributes");
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[0] = CommandIDGetAppAttributes;
|
||||
index ++;
|
||||
memcpy(&buffer[index], appidentifier, appidentifier_len);
|
||||
@@ -215,7 +235,7 @@ void esp_get_app_attributes(uint8_t *appidentifier, uint16_t appidentifier_len,
|
||||
|
||||
void esp_perform_notification_action(uint8_t *notificationUID, uint8_t ActionID)
|
||||
{
|
||||
uint8_t buffer[600] = {0};
|
||||
uint8_t buffer[ANCS_CMD_BUFFER_MAX_SIZE] = {0};
|
||||
uint32_t index = 0;
|
||||
buffer[0] = CommandIDPerformNotificationAction;
|
||||
index ++;
|
||||
@@ -517,6 +537,12 @@ static void gattc_profile_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
|
||||
esp_get_notification_attributes(notificationUID, sizeof(p_attr)/sizeof(esp_noti_attr_list_t), p_attr);
|
||||
}
|
||||
} else if (param->notify.handle == gl_profile_tab[PROFILE_A_APP_ID].data_source_handle) {
|
||||
if ((data_buffer.len + param->notify.value_len) > sizeof(data_buffer.buffer)) {
|
||||
ESP_LOGE(BLE_ANCS_TAG, "Data source buffer overflow detected, discarding data");
|
||||
memset(data_buffer.buffer, 0, sizeof(data_buffer.buffer));
|
||||
data_buffer.len = 0;
|
||||
break;
|
||||
}
|
||||
memcpy(&data_buffer.buffer[data_buffer.len], param->notify.value, param->notify.value_len);
|
||||
data_buffer.len += param->notify.value_len;
|
||||
if (param->notify.value_len == (gl_profile_tab[PROFILE_A_APP_ID].MTU_size - 3)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "esp_eddystone_protocol.h"
|
||||
#include "esp_eddystone_api.h"
|
||||
|
||||
#define EDDYSTONE_URL_BUF_SIZE 100
|
||||
|
||||
/* Declare static functions */
|
||||
static esp_err_t esp_eddystone_uid_received(const uint8_t* buf, uint8_t len, esp_eddystone_result_t* res);
|
||||
@@ -101,18 +102,33 @@ static esp_err_t esp_eddystone_uid_received(const uint8_t* buf, uint8_t len, esp
|
||||
static char* esp_eddystone_resolve_url_scheme(const uint8_t *url_start, const uint8_t *url_end)
|
||||
{
|
||||
int pos = 0;
|
||||
static char url_buf[100] = {0};
|
||||
static char url_buf[EDDYSTONE_URL_BUF_SIZE] = {0};
|
||||
const uint8_t *p = url_start;
|
||||
int written;
|
||||
|
||||
pos += sprintf(&url_buf[pos], "%s", eddystone_url_prefix[*p++]);
|
||||
// Security fix: Use snprintf instead of sprintf to prevent buffer overflow
|
||||
written = snprintf(&url_buf[pos], EDDYSTONE_URL_BUF_SIZE - pos, "%s", eddystone_url_prefix[*p++]);
|
||||
if (written < 0 || written >= (EDDYSTONE_URL_BUF_SIZE - pos)) {
|
||||
url_buf[EDDYSTONE_URL_BUF_SIZE - 1] = '\0';
|
||||
return url_buf;
|
||||
}
|
||||
pos += written;
|
||||
|
||||
for (; p <= url_end; p++) {
|
||||
if (esp_eddystone_is_char_invalid((*p))) {
|
||||
pos += sprintf(&url_buf[pos], "%s", eddystone_url_encoding[*p]);
|
||||
} else {
|
||||
pos += sprintf(&url_buf[pos], "%c", *p);
|
||||
if (pos >= EDDYSTONE_URL_BUF_SIZE - 1) {
|
||||
break;
|
||||
}
|
||||
if (esp_eddystone_is_char_invalid((*p))) {
|
||||
written = snprintf(&url_buf[pos], EDDYSTONE_URL_BUF_SIZE - pos, "%s", eddystone_url_encoding[*p]);
|
||||
} else {
|
||||
written = snprintf(&url_buf[pos], EDDYSTONE_URL_BUF_SIZE - pos, "%c", *p);
|
||||
}
|
||||
if (written < 0 || written >= (EDDYSTONE_URL_BUF_SIZE - pos)) {
|
||||
break;
|
||||
}
|
||||
pos += written;
|
||||
}
|
||||
url_buf[EDDYSTONE_URL_BUF_SIZE - 1] = '\0';
|
||||
return url_buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -277,20 +277,25 @@ static bool store_wr_buffer(esp_ble_gatts_cb_param_t *p_data)
|
||||
ESP_LOGI(GATTS_TABLE_TAG, "malloc error %s %d", __func__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
temp_spp_recv_data_node_p1->len = p_data->write.len;
|
||||
temp_spp_recv_data_node_p1->next_node = NULL;
|
||||
temp_spp_recv_data_node_p1->node_buff = (uint8_t *)malloc(p_data->write.len);
|
||||
if (temp_spp_recv_data_node_p1->node_buff == NULL) {
|
||||
ESP_LOGI(GATTS_TABLE_TAG, "malloc error %s %d\n", __func__, __LINE__);
|
||||
// Security fix: Free the node and return false to prevent memory leak
|
||||
free(temp_spp_recv_data_node_p1);
|
||||
temp_spp_recv_data_node_p1 = NULL;
|
||||
return false;
|
||||
}
|
||||
memcpy(temp_spp_recv_data_node_p1->node_buff, p_data->write.value, p_data->write.len);
|
||||
|
||||
// Security fix: Link to list only after successful allocation
|
||||
if(temp_spp_recv_data_node_p2 != NULL){
|
||||
temp_spp_recv_data_node_p2->next_node = temp_spp_recv_data_node_p1;
|
||||
}
|
||||
temp_spp_recv_data_node_p1->len = p_data->write.len;
|
||||
SppRecvDataBuff.buff_size += p_data->write.len;
|
||||
temp_spp_recv_data_node_p1->next_node = NULL;
|
||||
temp_spp_recv_data_node_p1->node_buff = (uint8_t *)malloc(p_data->write.len);
|
||||
temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1;
|
||||
if (temp_spp_recv_data_node_p1->node_buff == NULL) {
|
||||
ESP_LOGI(GATTS_TABLE_TAG, "malloc error %s %d\n", __func__, __LINE__);
|
||||
temp_spp_recv_data_node_p1->len = 0;
|
||||
} else {
|
||||
memcpy(temp_spp_recv_data_node_p1->node_buff,p_data->write.value,p_data->write.len);
|
||||
}
|
||||
SppRecvDataBuff.buff_size += p_data->write.len;
|
||||
|
||||
if(SppRecvDataBuff.node_num == 0){
|
||||
SppRecvDataBuff.first_node = temp_spp_recv_data_node_p1;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
//#define SUPPORT_HEARTBEAT
|
||||
//#define SPP_DEBUG_MODE
|
||||
|
||||
#define spp_sprintf(s,...) sprintf((char*)(s), ##__VA_ARGS__)
|
||||
#define SPP_DATA_MAX_LEN (512)
|
||||
#define SPP_CMD_MAX_LEN (20)
|
||||
#define SPP_STATUS_MAX_LEN (20)
|
||||
|
||||
@@ -282,7 +282,8 @@ void example_write_event_env(esp_gatt_if_t gatts_if, prepare_type_env_t *prepare
|
||||
}
|
||||
}
|
||||
|
||||
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)malloc(sizeof(esp_gatt_rsp_t));
|
||||
// Security fix: Use calloc to ensure memory is zero-initialized
|
||||
esp_gatt_rsp_t *gatt_rsp = (esp_gatt_rsp_t *)calloc(1, sizeof(esp_gatt_rsp_t));
|
||||
if (gatt_rsp) {
|
||||
gatt_rsp->attr_value.len = param->write.len;
|
||||
gatt_rsp->attr_value.handle = param->write.handle;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -131,8 +131,24 @@ static struct gatts_profile_inst gl_profile_tab[PROFILE_NUM] = {
|
||||
};
|
||||
static void ble_init_adv_data(const char *name)
|
||||
{
|
||||
int len = strlen(name);
|
||||
uint8_t raw_adv_data[len+5];
|
||||
if (name == NULL) {
|
||||
ESP_LOGE(BT_BLE_COEX_TAG, "ble_init_adv_data: name is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t len = strlen(name);
|
||||
// ADV data max is 31 bytes; overhead is 5 bytes (Flags: 3, Name header: 2)
|
||||
#define ADV_DATA_MAX_LEN 31
|
||||
#define ADV_DATA_OVERHEAD 5
|
||||
|
||||
if (len > (ADV_DATA_MAX_LEN - ADV_DATA_OVERHEAD)) {
|
||||
ESP_LOGW(BT_BLE_COEX_TAG, "ADV name too long (%d), truncating to %d", (int)len, ADV_DATA_MAX_LEN - ADV_DATA_OVERHEAD);
|
||||
len = ADV_DATA_MAX_LEN - ADV_DATA_OVERHEAD;
|
||||
}
|
||||
|
||||
uint8_t raw_adv_data[ADV_DATA_MAX_LEN];
|
||||
size_t adv_data_len = len + ADV_DATA_OVERHEAD;
|
||||
|
||||
//flag
|
||||
raw_adv_data[0] = 2;
|
||||
raw_adv_data[1] = ESP_BT_EIR_TYPE_FLAGS;
|
||||
@@ -140,16 +156,14 @@ static void ble_init_adv_data(const char *name)
|
||||
//adv name
|
||||
raw_adv_data[3] = len + 1;
|
||||
raw_adv_data[4] = ESP_BLE_AD_TYPE_NAME_CMPL;
|
||||
for (int i = 0;i < len;i++)
|
||||
{
|
||||
raw_adv_data[i+5] = *(name++);
|
||||
}
|
||||
memcpy(&raw_adv_data[5], name, len);
|
||||
|
||||
//The length of adv data must be less than 31 bytes
|
||||
esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, sizeof(raw_adv_data));
|
||||
esp_err_t raw_adv_ret = esp_ble_gap_config_adv_data_raw(raw_adv_data, adv_data_len);
|
||||
if (raw_adv_ret){
|
||||
ESP_LOGE(BT_BLE_COEX_TAG, "config raw adv data failed, error code = 0x%x ", raw_adv_ret);
|
||||
}
|
||||
esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_adv_data, sizeof(raw_adv_data));
|
||||
esp_err_t raw_scan_ret = esp_ble_gap_config_scan_rsp_data_raw(raw_adv_data, adv_data_len);
|
||||
if (raw_scan_ret){
|
||||
ESP_LOGE(BT_BLE_COEX_TAG, "config raw scan rsp data failed, error code = 0x%x", raw_scan_ret);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
struct blufi_security {
|
||||
#define DH_SELF_PUB_KEY_LEN 128
|
||||
#define DH_PARAM_LEN_MAX 1024
|
||||
uint8_t self_public_key[DH_SELF_PUB_KEY_LEN];
|
||||
#define SHARE_KEY_LEN 128
|
||||
uint8_t share_key[SHARE_KEY_LEN];
|
||||
@@ -83,6 +84,13 @@ void blufi_dh_negotiate_data_handler(uint8_t *data, int len, uint8_t **output_da
|
||||
switch (type) {
|
||||
case SEC_TYPE_DH_PARAM_LEN:
|
||||
blufi_sec->dh_param_len = ((data[1]<<8)|data[2]);
|
||||
// Security fix: Limit DH param length to prevent DoS via large memory allocation
|
||||
if (blufi_sec->dh_param_len == 0 || blufi_sec->dh_param_len > DH_PARAM_LEN_MAX) {
|
||||
BLUFI_ERROR("%s, invalid dh param len %d\n", __func__, blufi_sec->dh_param_len);
|
||||
blufi_sec->dh_param_len = 0;
|
||||
btc_blufi_report_error(ESP_BLUFI_DH_PARAM_ERROR);
|
||||
return;
|
||||
}
|
||||
if (blufi_sec->dh_param) {
|
||||
free(blufi_sec->dh_param);
|
||||
blufi_sec->dh_param = NULL;
|
||||
|
||||
@@ -278,6 +278,9 @@ static void handle_bt_device_result(struct disc_res_param *disc_res)
|
||||
GAP_DBG_PRINTF(", %s: ", gap_bt_prop_type_names[prop->type]);
|
||||
}
|
||||
if (prop->type == ESP_BT_GAP_DEV_PROP_BDNAME) {
|
||||
if (prop->val == NULL) {
|
||||
continue;
|
||||
}
|
||||
name = (uint8_t *)prop->val;
|
||||
name_len = strlen((const char *)name);
|
||||
GAP_DBG_PRINTF("%s", (const char *)name);
|
||||
|
||||
@@ -164,7 +164,7 @@ void hid_demo_task(void *pvParameters)
|
||||
printf("] srv 0x%03x, ", r->bt.cod.service);
|
||||
print_uuid(&r->bt.uuid);
|
||||
printf(", ");
|
||||
if (strncmp(r->name, remote_device_name, strlen(remote_device_name)) == 0) {
|
||||
if (r->name && strncmp(r->name, remote_device_name, strlen(remote_device_name)) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ void hid_demo_task(void *pvParameters)
|
||||
}
|
||||
|
||||
#if CONFIG_BT_HID_HOST_ENABLED
|
||||
if (cr && strncmp(cr->name, remote_device_name, strlen(remote_device_name)) == 0) {
|
||||
if (cr && cr->name && strncmp(cr->name, remote_device_name, strlen(remote_device_name)) == 0) {
|
||||
esp_hidh_dev_open(cr->bda, cr->transport, cr->ble.addr_type);
|
||||
}
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user