mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
fix(ble/bluedroid): Fix potential out-of-bounds issue
- add length check in hci_hal_h4_hdl_rx_packet to prevent OOB
- add adv data length check in btm_ble_cache_adv_data
- add indicate data length check in BTA_GATTS_HandleValueIndication
- add report length check in bta_hh_parse_keybd_rpt
- add report length check in BTA_HdSendReport
- add descriptor length check in BTA_HdRegisterApp
- prevent buffer overflow in attribute processing
(cherry picked from commit 71efec78c5)
Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
|
||||
Reference in New Issue
Block a user