mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'bugfix/fix_ble_security_issue_2025_v5.3' into 'release/v5.3'
Fix potential CVE-2024-0039 out-of-bounds write in attp_build_value_cmd (v5.3) See merge request espressif/esp-idf!43805
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (adv_params == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_ACT_START_ADV;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (remote_device == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN;
|
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)
|
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
|
// Static device address: First two bits are '11', rest is random
|
||||||
rand_addr[0] = 0xC0 | (esp_random() & 0x3F);
|
rand_addr[0] = 0xC0 | (esp_random() & 0x3F);
|
||||||
for (int i = 1; i < 6; i++) {
|
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)
|
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
|
// Non-resolvable private address: First two bits are '00', rest is random
|
||||||
rand_addr[0] = (esp_random() & 0x3F);
|
rand_addr[0] = (esp_random() & 0x3F);
|
||||||
for (int i = 1; i < 6; i++) {
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (rand_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_ACT_SET_RAND_ADDRESS;
|
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);
|
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;
|
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;
|
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) &&
|
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(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) &&
|
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__);
|
LOG_ERROR("%s, bluedroid status error", __func__);
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
if (local_used_addr == NULL || addr_type == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
if(!BTM_BleGetCurrentAddress(local_used_addr, addr_type)) {
|
if(!BTM_BleGetCurrentAddress(local_used_addr, addr_type)) {
|
||||||
return ESP_FAIL;
|
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;
|
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) {
|
if (adv_data_len == 0) {
|
||||||
*length = 0;
|
*length = 0;
|
||||||
return NULL;
|
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;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (remote_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_ACT_READ_RSSI;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (bd_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_SET_ENCRYPTION_EVT;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (bd_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_SECURITY_RSP_EVT;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (bd_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_PASSKEY_REPLY_EVT;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (bd_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_CONFIRM_REPLY_EVT;
|
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_msg_t msg = {0};
|
||||||
btc_ble_gap_args_t arg;
|
btc_ble_gap_args_t arg;
|
||||||
|
|
||||||
|
if (bd_addr == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT;
|
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;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bd_addr == NULL || TK == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
btc_msg_t msg = {0};
|
btc_msg_t msg = {0};
|
||||||
btc_ble_gap_args_t arg;
|
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])
|
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;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (remote_device == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_DISCONNECT_EVT;
|
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;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (channels == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GAP_BLE;
|
msg.pid = BTC_PID_GAP_BLE;
|
||||||
msg.act = BTC_GAP_BLE_SET_AFH_CHANNELS;
|
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)
|
#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)
|
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};
|
esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
|
||||||
memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
||||||
creat_conn_params.remote_addr_type = remote_addr_type;
|
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)
|
#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)
|
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};
|
esp_ble_gatt_creat_conn_params_t creat_conn_params = {0};
|
||||||
memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
memcpy(creat_conn_params.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
||||||
creat_conn_params.remote_addr_type = remote_addr_type;
|
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);
|
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);
|
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
|
||||||
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
|
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
|
||||||
LOG_WARN("%s, The connection not created.", __func__);
|
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);
|
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);
|
tGATT_TCB *p_tcb = gatt_get_tcb_by_idx(conn_id);
|
||||||
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
|
if (!gatt_check_connection_state_by_tcb(p_tcb)) {
|
||||||
LOG_WARN("%s, The connection not created.", __func__);
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (server_bda == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
return ESP_GATT_INVALID_HANDLE;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (server_bda == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
if (handle == 0) {
|
if (handle == 0) {
|
||||||
return ESP_GATT_INVALID_HANDLE;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (remote_bda == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GATTC;
|
msg.pid = BTC_PID_GATTC;
|
||||||
msg.act = BTC_GATTC_ACT_CACHE_REFRESH;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (remote_bda == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GATTC;
|
msg.pid = BTC_PID_GATTC;
|
||||||
msg.act = BTC_GATTC_ACT_CACHE_CLEAN;
|
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);
|
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.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GATTC;
|
msg.pid = BTC_PID_GATTC;
|
||||||
msg.act = BTC_GATTC_ACT_CACHE_ASSOC;
|
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
|
* 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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (service_id == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GATTS;
|
msg.pid = BTC_PID_GATTS;
|
||||||
msg.act = BTC_GATTS_ACT_CREATE_SERVICE;
|
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);
|
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) {
|
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");
|
LOG_ERROR("The number of attribute should not be greater than CONFIG_BT_GATT_MAX_SR_ATTRIBUTES\n");
|
||||||
return ESP_ERR_INVALID_ARG;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (char_uuid == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
/* parameter validation check */
|
/* parameter validation check */
|
||||||
status = esp_ble_gatts_add_char_desc_param_check(char_val, control);
|
status = esp_ble_gatts_add_char_desc_param_check(char_val, control);
|
||||||
if (status != ESP_OK){
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (descr_uuid == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
/* parameter validation check */
|
/* parameter validation check */
|
||||||
status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control);
|
status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control);
|
||||||
if (status != ESP_OK){
|
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);
|
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) {
|
if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
|
||||||
*length = 0;
|
*length = 0;
|
||||||
return ESP_GATT_INVALID_HANDLE;
|
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);
|
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||||
|
|
||||||
|
if (remote_bda == NULL) {
|
||||||
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
msg.sig = BTC_SIG_API_CALL;
|
msg.sig = BTC_SIG_API_CALL;
|
||||||
msg.pid = BTC_PID_GATTS;
|
msg.pid = BTC_PID_GATTS;
|
||||||
msg.act = BTC_GATTS_ACT_OPEN;
|
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_max_len = attr_val->attr_max_len;
|
||||||
p_buf->attr_val.attr_val = (uint8_t *)osi_malloc(len);
|
p_buf->attr_val.attr_val = (uint8_t *)osi_malloc(len);
|
||||||
if(p_buf->attr_val.attr_val != NULL){
|
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,
|
void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len,
|
||||||
UINT8 *p_data, BOOLEAN need_confirm)
|
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;
|
tBTA_GATTS_API_INDICATION *p_buf;
|
||||||
UINT16 len = sizeof(tBTA_GATTS_API_INDICATION);
|
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)
|
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;
|
tBTA_HD_REGISTER_APP *p_buf;
|
||||||
APPL_TRACE_API("%s", __func__);
|
APPL_TRACE_API("%s", __func__);
|
||||||
if ((p_buf = (tBTA_HD_REGISTER_APP *)osi_malloc(sizeof(tBTA_HD_REGISTER_APP))) != NULL) {
|
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);
|
__func__, p_report->len, BTA_HD_REPORT_LEN);
|
||||||
return;
|
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) {
|
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->hdr.event = BTA_HD_API_SEND_REPORT_EVT;
|
||||||
p_buf->use_intr = p_report->use_intr;
|
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;
|
UINT16 xx, yy, key_idx = 0;
|
||||||
UINT8 this_report[BTA_HH_MAX_RPT_CHARS];
|
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
|
#if BTA_HH_DEBUG
|
||||||
APPL_TRACE_DEBUG("bta_hh_parse_keybd_rpt: (report=%p, report_len=%d) called",
|
APPL_TRACE_DEBUG("bta_hh_parse_keybd_rpt: (report=%p, report_len=%d) called",
|
||||||
p_report, report_len);
|
p_report, report_len);
|
||||||
@@ -463,7 +475,7 @@ void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
|
|||||||
|
|
||||||
if (bta_hh_cb.p_cback) {
|
if (bta_hh_cb.p_cback) {
|
||||||
(*bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH*)&status);
|
(*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));
|
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);
|
STREAM_TO_UINT8(length, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((length + hdr_size) != packet->len) {
|
// Prevents integer wrap-around when calculating (length + hdr_size).
|
||||||
HCI_TRACE_ERROR("Wrong packet length type=%d hdr_len=%d pd_len=%d "
|
if (length != (packet->len - hdr_size)) {
|
||||||
"pkt_len=%d", type, hdr_size, length, packet->len);
|
HCI_TRACE_ERROR("%s: SECURITY: parameter length (%d) exceeds packet bounds (%d)",
|
||||||
|
__func__, length, packet->len - hdr_size);
|
||||||
osi_free(packet);
|
osi_free(packet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -456,10 +456,12 @@ static bool filter_incoming_event(BT_HDR *packet)
|
|||||||
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
|
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
|
||||||
STREAM_TO_UINT16(opcode, stream);
|
STREAM_TO_UINT16(opcode, stream);
|
||||||
wait_entry = get_waiting_command(opcode);
|
wait_entry = get_waiting_command(opcode);
|
||||||
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
|
|
||||||
if (!wait_entry) {
|
if (!wait_entry) {
|
||||||
HCI_TRACE_WARNING("%s command complete event with no matching command. opcode: 0x%x.", __func__, opcode);
|
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);
|
metadata->command_complete_cb(packet, metadata->context);
|
||||||
#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
#if (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||||
BlE_SYNC *sync_info = btsnd_hcic_ble_get_sync_info();
|
BlE_SYNC *sync_info = btsnd_hcic_ble_get_sync_info();
|
||||||
@@ -486,10 +488,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
|
// If a command generates a command status event, it won't be getting a command complete event
|
||||||
|
|
||||||
wait_entry = get_waiting_command(opcode);
|
wait_entry = get_waiting_command(opcode);
|
||||||
metadata = (hci_cmd_metadata_t *)(wait_entry->data);
|
|
||||||
if (!wait_entry) {
|
if (!wait_entry) {
|
||||||
HCI_TRACE_WARNING("%s command status event with no matching command. opcode: 0x%x", __func__, opcode);
|
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);
|
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 *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);
|
assert(stream != NULL);
|
||||||
STREAM_TO_UINT16(*data_size_ptr, stream);
|
STREAM_TO_UINT16(*data_size_ptr, stream);
|
||||||
STREAM_TO_UINT8(*acl_buffer_count_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);
|
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;
|
uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE;
|
||||||
if (full_length <= packet->len) {
|
if (full_length <= packet->len) {
|
||||||
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->offset += HCI_ACL_PREAMBLE_SIZE; // skip ACL preamble
|
||||||
packet->len -= HCI_ACL_PREAMBLE_SIZE;
|
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;
|
uint16_t projected_offset = partial_packet->offset + packet->len;
|
||||||
if (projected_offset > partial_packet->len) { // len stores the expected length
|
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);
|
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;
|
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
|
// adv terminated due to connection, save the adv handle and connection handle
|
||||||
if(params->status == 0x00) {
|
if(params->status == 0x00) {
|
||||||
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
|
adv_record[params->adv_handle].ter_con_handle = params->conn_handle;
|
||||||
|
|||||||
@@ -3113,6 +3113,13 @@ void btm_ble_cache_adv_data(BD_ADDR bda, tBTM_INQ_RESULTS *p_cur, UINT8 data_len
|
|||||||
p_cur->scan_rsp_len = 0;
|
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) {
|
if (data_len > 0) {
|
||||||
p_cache = &p_le_inq_cb->adv_data_cache[p_le_inq_cb->adv_len];
|
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) {
|
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));
|
memset(p_clcb, 0, sizeof(tGAP_CLCB));
|
||||||
p_clcb->in_use = TRUE;
|
p_clcb->in_use = TRUE;
|
||||||
memcpy (p_clcb->bda, bda, BD_ADDR_LEN);
|
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) {
|
switch (op_type) {
|
||||||
case GATT_UUID_GAP_PREF_CONN_PARAM:
|
case GATT_UUID_GAP_PREF_CONN_PARAM:
|
||||||
GAP_TRACE_EVENT ("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 */
|
/* Extract the peripheral preferred connection parameters and save them */
|
||||||
|
|
||||||
STREAM_TO_UINT16 (min, pp);
|
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:
|
case GATT_UUID_GAP_DEVICE_NAME:
|
||||||
GAP_TRACE_EVENT ("GATT_UUID_GAP_DEVICE_NAME\n");
|
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) {
|
if (len > GAP_CHAR_DEV_NAME_SIZE) {
|
||||||
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;
|
break;
|
||||||
|
|
||||||
case GATT_UUID_GAP_CENTRAL_ADDR_RESOL:
|
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);
|
gap_ble_cl_op_cmpl(p_clcb, TRUE, 1, pp);
|
||||||
break;
|
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);
|
memcpy (&p_ccb->rem_dev_address[0], p_rem_bda, BD_ADDR_LEN);
|
||||||
} else if (!is_server) {
|
} 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);
|
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) {
|
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->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);
|
gap_checks_con_flags (p_ccb);
|
||||||
} else {
|
} 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);
|
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);
|
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);
|
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->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 {
|
} else {
|
||||||
osi_free (p_msg);
|
osi_free (p_msg);
|
||||||
}
|
}
|
||||||
@@ -1030,7 +1038,9 @@ static void gap_congestion_ind (UINT16 lcid, BOOLEAN is_congested)
|
|||||||
p_ccb->is_congested = is_congested;
|
p_ccb->is_congested = is_congested;
|
||||||
|
|
||||||
event = (is_congested) ? GAP_EVT_CONN_CONGESTED : GAP_EVT_CONN_UNCONGESTED;
|
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) {
|
if (!is_congested) {
|
||||||
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL) {
|
while ((p_buf = (BT_HDR *)fixed_queue_dequeue(p_ccb->tx_queue, 0)) != NULL) {
|
||||||
|
|||||||
@@ -285,57 +285,89 @@ BT_HDR *attp_build_opcode_cmd(UINT8 op_code)
|
|||||||
** Returns None.
|
** Returns None.
|
||||||
**
|
**
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
BT_HDR *attp_build_value_cmd (UINT16 payload_size, UINT8 op_code, UINT16 handle,
|
BT_HDR *attp_build_value_cmd(UINT16 payload_size, UINT8 op_code,
|
||||||
UINT16 offset, UINT16 len, UINT8 *p_data)
|
UINT16 handle, UINT16 offset,
|
||||||
|
UINT16 len, UINT8 *p_data)
|
||||||
{
|
{
|
||||||
BT_HDR *p_buf = NULL;
|
BT_HDR *p_buf = NULL;
|
||||||
UINT8 *p, *pp, pair_len, *p_pair_len;
|
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) {
|
#define CHECK_SIZE() \
|
||||||
p = pp = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
|
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);
|
/* allocate buffer with extra space for L2CAP offset */
|
||||||
p_buf->offset = L2CAP_MIN_OFFSET;
|
p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR) + payload_size + L2CAP_MIN_OFFSET);
|
||||||
p_buf->len = 1;
|
if (!p_buf) return NULL;
|
||||||
|
|
||||||
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
p = pp = (UINT8 *)(p_buf + 1) + L2CAP_MIN_OFFSET;
|
||||||
p_pair_len = p;
|
|
||||||
pair_len = len + 2;
|
CHECK_SIZE();
|
||||||
UINT8_TO_STREAM (p, pair_len);
|
UINT8_TO_STREAM(p, op_code);
|
||||||
p_buf->len += 1;
|
p_buf->offset = L2CAP_MIN_OFFSET;
|
||||||
}
|
|
||||||
if (op_code != GATT_RSP_READ_BLOB && op_code != GATT_RSP_READ && op_code != GATT_HANDLE_MULTI_VALUE_NOTIF) {
|
/* handle Read By Type response: reserve space for pair_len */
|
||||||
UINT16_TO_STREAM (p, handle);
|
if (op_code == GATT_RSP_READ_BY_TYPE) {
|
||||||
p_buf->len += 2;
|
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 ) {
|
size_now += len;
|
||||||
UINT16_TO_STREAM (p, offset);
|
CHECK_SIZE();
|
||||||
p_buf->len += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(payload_size < GATT_DEF_BLE_MTU_SIZE || payload_size > GATT_MAX_MTU_SIZE) {
|
ARRAY_TO_STREAM(p, p_data, len);
|
||||||
GATT_TRACE_ERROR("invalid payload_size %d", payload_size);
|
}
|
||||||
|
|
||||||
|
/* 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);
|
osi_free(p_buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
*p_pair_len = (UINT8)pair_len;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update buffer length */
|
||||||
|
p_buf->len = (UINT16)size_now;
|
||||||
|
|
||||||
|
#undef CHECK_SIZE
|
||||||
|
|
||||||
return p_buf;
|
return p_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ static const UINT16 disc_type_to_uuid[GATT_DISC_MAX] = {
|
|||||||
0 /* no type filtering for DISC_CHAR_DSCPT */
|
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);}
|
#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);
|
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_TRACE_ERROR("illegal prepare write response length, discard");
|
||||||
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
|
gatt_end_operation(p_clcb, GATT_INVALID_PDU, &value);
|
||||||
return;
|
return;
|
||||||
@@ -701,7 +701,7 @@ void gatt_process_notification(tGATT_TCB *p_tcb, UINT8 op_code,
|
|||||||
}
|
}
|
||||||
p_tcb->ind_count = 0;
|
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
|
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++) {
|
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;
|
handle_len = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_len -= handle_len; /* substract the handle pairs bytes */
|
value_len -= handle_len; /* subtract the handle pairs bytes */
|
||||||
len -= 1;
|
len -= 1;
|
||||||
|
|
||||||
while (len >= (handle_len + value_len)) {
|
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);
|
gatt_end_operation(p_clcb, GATT_SUCCESS, (void *)p);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else { /* discover characterisitic */
|
} else { /* discover characteristic */
|
||||||
STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
|
STREAM_TO_UINT8 (record_value.dclr_value.char_prop, p);
|
||||||
STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
|
STREAM_TO_UINT16(record_value.dclr_value.val_handle, p);
|
||||||
if (!GATT_HANDLE_IS_VALID(record_value.dclr_value.val_handle)) {
|
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 */
|
if (len == (p_tcb->payload_size - 1) && /* full packet for read or read blob rsp */
|
||||||
len + offset < GATT_MAX_ATTR_LEN) {
|
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);
|
offset, len, p_clcb->counter);
|
||||||
gatt_act_read(p_clcb, p_clcb->counter);
|
gatt_act_read(p_clcb, p_clcb->counter);
|
||||||
} else { /* end of request, send callback */
|
} 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;
|
return GATT_APP_RSP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((p_attr->p_value != NULL) &&
|
if (p_attr->p_value == NULL || p_attr->p_value->attr_val.attr_val == 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)){
|
|
||||||
GATT_TRACE_ERROR("Error in %s, line=%d, %s should not be NULL here\n", __func__, __LINE__, \
|
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");
|
(p_attr->p_value == NULL) ? "p_value" : "attr_val.attr_val");
|
||||||
return GATT_UNKNOWN_ERROR;
|
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;
|
p_attr = (tGATT_ATTR16 *)p_attr->p_next;
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ enum {
|
|||||||
};
|
};
|
||||||
typedef UINT8 tSMP_BR_STATE;
|
typedef UINT8 tSMP_BR_STATE;
|
||||||
|
|
||||||
/* random and encrption activity state */
|
/* random and encryption activity state */
|
||||||
enum {
|
enum {
|
||||||
SMP_GEN_COMPARE = 1,
|
SMP_GEN_COMPARE = 1,
|
||||||
SMP_GEN_CONFIRM,
|
SMP_GEN_CONFIRM,
|
||||||
@@ -363,6 +363,9 @@ extern tSMP_CB *smp_cb_ptr;
|
|||||||
/* Functions provided by att_main.c */
|
/* Functions provided by att_main.c */
|
||||||
extern void smp_init (void);
|
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 */
|
/* smp main */
|
||||||
extern void smp_sm_event(tSMP_CB *p_cb, tSMP_EVENT event, void *p_data);
|
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)
|
static void smp_data_received(UINT16 channel, BD_ADDR bd_addr, BT_HDR *p_buf)
|
||||||
{
|
{
|
||||||
tSMP_CB *p_cb = &smp_cb;
|
tSMP_CB *p_cb = &smp_cb;
|
||||||
UINT8 *p = (UINT8 *)(p_buf + 1) + p_buf->offset;
|
UINT8 *p;
|
||||||
UINT8 cmd ;
|
UINT8 cmd;
|
||||||
SMP_TRACE_EVENT ("\nSMDBG l2c %s\n", __FUNCTION__);
|
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);
|
STREAM_TO_UINT8(cmd, p);
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if ((SMP_OPCODE_MAX < cmd) || (SMP_OPCODE_MIN > cmd)) {
|
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);
|
osi_free (p_buf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
#define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/)
|
#define SMP_PAIR_KEYPR_NOTIF_SIZE (1 /* opcode */ + 1 /*Notif Type*/)
|
||||||
|
|
||||||
/* SMP command sizes per spec */
|
/* SMP command sizes per spec */
|
||||||
static const UINT8 smp_cmd_size_per_spec[] = {
|
const UINT8 smp_cmd_size_per_spec[] = {
|
||||||
0,
|
0,
|
||||||
SMP_PAIRING_REQ_SIZE, /* 0x01: pairing request */
|
SMP_PAIRING_REQ_SIZE, /* 0x01: pairing request */
|
||||||
SMP_PAIRING_REQ_SIZE, /* 0x02: pairing response */
|
SMP_PAIRING_REQ_SIZE, /* 0x02: pairing response */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@@ -127,14 +127,24 @@ void esp_receive_apple_data_source(uint8_t *message, uint16_t message_len)
|
|||||||
switch (Command_id)
|
switch (Command_id)
|
||||||
{
|
{
|
||||||
case CommandIDGetNotificationAttributes: {
|
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 NotificationUID = (message[1]) | (message[2]<< 8) | (message[3]<< 16) | (message[4] << 24);
|
||||||
uint32_t remian_attr_len = message_len - 5;
|
uint32_t remian_attr_len = message_len - 5;
|
||||||
uint8_t *attrs = &message[5];
|
uint8_t *attrs = &message[5];
|
||||||
ESP_LOGI(BLE_ANCS_TAG, "recevice Notification Attributes response Command_id %d NotificationUID %" PRIu32, Command_id, NotificationUID);
|
ESP_LOGI(BLE_ANCS_TAG, "recevice Notification Attributes response Command_id %d NotificationUID %" PRIu32, Command_id, NotificationUID);
|
||||||
while(remian_attr_len > 0) {
|
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];
|
uint8_t AttributeID = attrs[0];
|
||||||
uint16_t len = attrs[1] | (attrs[2] << 8);
|
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");
|
ESP_LOGE(BLE_ANCS_TAG, "data error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@@ -31,6 +31,8 @@
|
|||||||
#define ADV_CONFIG_FLAG (1 << 0)
|
#define ADV_CONFIG_FLAG (1 << 0)
|
||||||
#define SCAN_RSP_CONFIG_FLAG (1 << 1)
|
#define SCAN_RSP_CONFIG_FLAG (1 << 1)
|
||||||
#define INVALID_HANDLE 0
|
#define INVALID_HANDLE 0
|
||||||
|
#define ANCS_CMD_BUFFER_MAX_SIZE 600
|
||||||
|
|
||||||
static uint8_t adv_config_done = 0;
|
static uint8_t adv_config_done = 0;
|
||||||
static bool get_service = false;
|
static bool get_service = false;
|
||||||
static esp_gattc_char_elem_t *char_elem_result = NULL;
|
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)
|
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;
|
uint32_t index = 0;
|
||||||
|
|
||||||
cmd[0] = CommandIDGetNotificationAttributes;
|
cmd[0] = CommandIDGetNotificationAttributes;
|
||||||
index ++;
|
index ++;
|
||||||
memcpy(&cmd[index], notificationUID, ESP_NOTIFICATIONUID_LEN);
|
memcpy(&cmd[index], notificationUID, ESP_NOTIFICATIONUID_LEN);
|
||||||
index += ESP_NOTIFICATIONUID_LEN;
|
index += ESP_NOTIFICATIONUID_LEN;
|
||||||
while(num_attr > 0) {
|
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;
|
cmd[index ++] = p_attr->noti_attribute_id;
|
||||||
if (p_attr->attribute_len > 0) {
|
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;
|
||||||
cmd[index ++] = (p_attr->attribute_len << 8);
|
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)
|
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;
|
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;
|
buffer[0] = CommandIDGetAppAttributes;
|
||||||
index ++;
|
index ++;
|
||||||
memcpy(&buffer[index], appidentifier, appidentifier_len);
|
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)
|
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;
|
uint32_t index = 0;
|
||||||
buffer[0] = CommandIDPerformNotificationAction;
|
buffer[0] = CommandIDPerformNotificationAction;
|
||||||
index ++;
|
index ++;
|
||||||
@@ -518,6 +538,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);
|
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) {
|
} 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);
|
memcpy(&data_buffer.buffer[data_buffer.len], param->notify.value, param->notify.value_len);
|
||||||
data_buffer.len += 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)) {
|
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
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "esp_eddystone_protocol.h"
|
#include "esp_eddystone_protocol.h"
|
||||||
#include "esp_eddystone_api.h"
|
#include "esp_eddystone_api.h"
|
||||||
|
|
||||||
|
#define EDDYSTONE_URL_BUF_SIZE 100
|
||||||
|
|
||||||
/* Declare static functions */
|
/* Declare static functions */
|
||||||
static esp_err_t esp_eddystone_uid_received(const uint8_t* buf, uint8_t len, esp_eddystone_result_t* res);
|
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)
|
static char* esp_eddystone_resolve_url_scheme(const uint8_t *url_start, const uint8_t *url_end)
|
||||||
{
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
static char url_buf[100] = {0};
|
static char url_buf[EDDYSTONE_URL_BUF_SIZE] = {0};
|
||||||
const uint8_t *p = url_start;
|
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++) {
|
for (; p <= url_end; p++) {
|
||||||
if (esp_eddystone_is_char_invalid((*p))) {
|
if (pos >= EDDYSTONE_URL_BUF_SIZE - 1) {
|
||||||
pos += sprintf(&url_buf[pos], "%s", eddystone_url_encoding[*p]);
|
break;
|
||||||
} else {
|
|
||||||
pos += sprintf(&url_buf[pos], "%c", *p);
|
|
||||||
}
|
}
|
||||||
|
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;
|
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__);
|
ESP_LOGI(GATTS_TABLE_TAG, "malloc error %s %d", __func__, __LINE__);
|
||||||
return false;
|
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){
|
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_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;
|
temp_spp_recv_data_node_p2 = temp_spp_recv_data_node_p1;
|
||||||
if (temp_spp_recv_data_node_p1->node_buff == NULL) {
|
SppRecvDataBuff.buff_size += p_data->write.len;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SppRecvDataBuff.node_num == 0){
|
if(SppRecvDataBuff.node_num == 0){
|
||||||
SppRecvDataBuff.first_node = temp_spp_recv_data_node_p1;
|
SppRecvDataBuff.first_node = temp_spp_recv_data_node_p1;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
//#define SUPPORT_HEARTBEAT
|
//#define SUPPORT_HEARTBEAT
|
||||||
//#define SPP_DEBUG_MODE
|
//#define SPP_DEBUG_MODE
|
||||||
|
|
||||||
#define spp_sprintf(s,...) sprintf((char*)(s), ##__VA_ARGS__)
|
|
||||||
#define SPP_DATA_MAX_LEN (512)
|
#define SPP_DATA_MAX_LEN (512)
|
||||||
#define SPP_CMD_MAX_LEN (20)
|
#define SPP_CMD_MAX_LEN (20)
|
||||||
#define SPP_STATUS_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) {
|
if (gatt_rsp) {
|
||||||
gatt_rsp->attr_value.len = param->write.len;
|
gatt_rsp->attr_value.len = param->write.len;
|
||||||
gatt_rsp->attr_value.handle = param->write.handle;
|
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
|
* 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)
|
static void ble_init_adv_data(const char *name)
|
||||||
{
|
{
|
||||||
int len = strlen(name);
|
if (name == NULL) {
|
||||||
uint8_t raw_adv_data[len+5];
|
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
|
//flag
|
||||||
raw_adv_data[0] = 2;
|
raw_adv_data[0] = 2;
|
||||||
raw_adv_data[1] = ESP_BT_EIR_TYPE_FLAGS;
|
raw_adv_data[1] = ESP_BT_EIR_TYPE_FLAGS;
|
||||||
@@ -140,16 +156,14 @@ static void ble_init_adv_data(const char *name)
|
|||||||
//adv name
|
//adv name
|
||||||
raw_adv_data[3] = len + 1;
|
raw_adv_data[3] = len + 1;
|
||||||
raw_adv_data[4] = ESP_BLE_AD_TYPE_NAME_CMPL;
|
raw_adv_data[4] = ESP_BLE_AD_TYPE_NAME_CMPL;
|
||||||
for (int i = 0;i < len;i++)
|
memcpy(&raw_adv_data[5], name, len);
|
||||||
{
|
|
||||||
raw_adv_data[i+5] = *(name++);
|
|
||||||
}
|
|
||||||
//The length of adv data must be less than 31 bytes
|
//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){
|
if (raw_adv_ret){
|
||||||
ESP_LOGE(BT_BLE_COEX_TAG, "config raw adv data failed, error code = 0x%x ", 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){
|
if (raw_scan_ret){
|
||||||
ESP_LOGE(BT_BLE_COEX_TAG, "config raw scan rsp data failed, error code = 0x%x", 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 {
|
struct blufi_security {
|
||||||
#define DH_SELF_PUB_KEY_LEN 128
|
#define DH_SELF_PUB_KEY_LEN 128
|
||||||
|
#define DH_PARAM_LEN_MAX 1024
|
||||||
uint8_t self_public_key[DH_SELF_PUB_KEY_LEN];
|
uint8_t self_public_key[DH_SELF_PUB_KEY_LEN];
|
||||||
#define SHARE_KEY_LEN 128
|
#define SHARE_KEY_LEN 128
|
||||||
uint8_t share_key[SHARE_KEY_LEN];
|
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) {
|
switch (type) {
|
||||||
case SEC_TYPE_DH_PARAM_LEN:
|
case SEC_TYPE_DH_PARAM_LEN:
|
||||||
blufi_sec->dh_param_len = ((data[1]<<8)|data[2]);
|
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) {
|
if (blufi_sec->dh_param) {
|
||||||
free(blufi_sec->dh_param);
|
free(blufi_sec->dh_param);
|
||||||
blufi_sec->dh_param = NULL;
|
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]);
|
GAP_DBG_PRINTF(", %s: ", gap_bt_prop_type_names[prop->type]);
|
||||||
}
|
}
|
||||||
if (prop->type == ESP_BT_GAP_DEV_PROP_BDNAME) {
|
if (prop->type == ESP_BT_GAP_DEV_PROP_BDNAME) {
|
||||||
|
if (prop->val == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
name = (uint8_t *)prop->val;
|
name = (uint8_t *)prop->val;
|
||||||
name_len = strlen((const char *)name);
|
name_len = strlen((const char *)name);
|
||||||
GAP_DBG_PRINTF("%s", (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);
|
printf("] srv 0x%03x, ", r->bt.cod.service);
|
||||||
print_uuid(&r->bt.uuid);
|
print_uuid(&r->bt.uuid);
|
||||||
printf(", ");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ void hid_demo_task(void *pvParameters)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_BT_HID_HOST_ENABLED
|
#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);
|
esp_hidh_dev_open(cr->bda, cr->transport, cr->ble.addr_type);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user