mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'bugfix/source_acp_miss_audio_cfg_evt_v5.2' into 'release/v5.2'
fix: enhanced packet length check in Bluedroid v5.2 See merge request espressif/esp-idf!45261
This commit is contained in:
@@ -283,6 +283,11 @@ tBTA_JV_STATUS BTA_JvStartDiscovery(BD_ADDR bd_addr, UINT16 num_uuid,
|
||||
tBTA_JV_API_START_DISCOVERY *p_msg;
|
||||
|
||||
APPL_TRACE_API( "BTA_JvStartDiscovery");
|
||||
if ((num_uuid > BTA_JV_MAX_UUIDS) || ((num_uuid > 0) && (p_uuid_list == NULL))) {
|
||||
APPL_TRACE_ERROR("invalid uuid list: num_uuid=%u", num_uuid);
|
||||
return BTA_JV_FAILURE;
|
||||
}
|
||||
|
||||
if ((p_msg = (tBTA_JV_API_START_DISCOVERY *)osi_malloc(sizeof(tBTA_JV_API_START_DISCOVERY))) != NULL) {
|
||||
p_msg->hdr.event = BTA_JV_API_START_DISCOVERY_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -652,7 +652,11 @@ static void btc_spp_start_discovery(btc_spp_args_t *arg)
|
||||
ret = ESP_SPP_NEED_INIT;
|
||||
break;
|
||||
}
|
||||
BTA_JvStartDiscovery(arg->start_discovery.bd_addr, arg->start_discovery.num_uuid, arg->start_discovery.p_uuid_list, NULL);
|
||||
tBTA_JV_STATUS status = BTA_JvStartDiscovery(arg->start_discovery.bd_addr, arg->start_discovery.num_uuid, arg->start_discovery.p_uuid_list, NULL);
|
||||
if (status != BTA_JV_SUCCESS) {
|
||||
BTC_TRACE_ERROR("%s SPP failed to start discovery\n", __func__);
|
||||
ret = ESP_SPP_NO_RESOURCE;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (ret != ESP_SPP_SUCCESS) {
|
||||
|
||||
@@ -481,6 +481,10 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet)
|
||||
packet->len--;
|
||||
if (type == HCI_BLE_EVENT) {
|
||||
#if (!CONFIG_BT_STACK_NO_LOG)
|
||||
if (packet->len < 1) {
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
uint8_t len = 0;
|
||||
STREAM_TO_UINT8(len, stream);
|
||||
#endif
|
||||
|
||||
@@ -447,12 +447,26 @@ static bool filter_incoming_event(BT_HDR *packet)
|
||||
uint8_t event_code;
|
||||
command_opcode_t opcode;
|
||||
|
||||
if (packet == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (packet->len < HCI_EVENT_PREAMBLE_SIZE) {
|
||||
HCI_TRACE_WARNING("dropping too short HCI event (len=%u)", packet->len);
|
||||
osi_free(packet);
|
||||
return true;
|
||||
}
|
||||
STREAM_TO_UINT8(event_code, stream);
|
||||
STREAM_SKIP_UINT8(stream); // Skip the parameter total length field
|
||||
|
||||
HCI_TRACE_DEBUG("Receive packet event_code=0x%x\n", event_code);
|
||||
|
||||
if (event_code == HCI_COMMAND_COMPLETE_EVT) {
|
||||
if (packet->len < HCI_EVENT_PREAMBLE_SIZE + HCI_CC_EVENT_MIN_PARAM_LEN) {
|
||||
HCI_TRACE_WARNING("dropping too short Command Complete (len=%u)", packet->len);
|
||||
osi_free(packet);
|
||||
return true;
|
||||
}
|
||||
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
|
||||
STREAM_TO_UINT16(opcode, stream);
|
||||
wait_entry = get_waiting_command(opcode);
|
||||
@@ -481,6 +495,11 @@ static bool filter_incoming_event(BT_HDR *packet)
|
||||
goto intercepted;
|
||||
} else if (event_code == HCI_COMMAND_STATUS_EVT) {
|
||||
uint8_t status;
|
||||
if (packet->len < HCI_EVENT_PREAMBLE_SIZE + HCI_CS_EVENT_MIN_PARAM_LEN) {
|
||||
HCI_TRACE_WARNING("dropping too short Command Status (len=%u)", packet->len);
|
||||
osi_free(packet);
|
||||
return true;
|
||||
}
|
||||
STREAM_TO_UINT8(status, stream);
|
||||
STREAM_TO_UINT8(hci_host_env.command_credits, stream);
|
||||
STREAM_TO_UINT16(opcode, stream);
|
||||
|
||||
@@ -27,5 +27,9 @@
|
||||
#define HCI_SCO_PREAMBLE_SIZE 3
|
||||
// 1 byte for event code, 1 byte for parameter length (Volume 2, Part E, 5.4.4)
|
||||
#define HCI_EVENT_PREAMBLE_SIZE 2
|
||||
// 1 byte for Num_HCI_Command_Packets, 2 bytes for Commnad_Opcode (Volume 4, Part E, 7.7.14)
|
||||
#define HCI_CC_EVENT_MIN_PARAM_LEN 3
|
||||
// 1 byte for status, 1 byte for Num_HCI_Command_Packets, 2 bytes for Commnad_Opcode (Volume 4, Part E, 7.7.15)
|
||||
#define HCI_CS_EVENT_MIN_PARAM_LEN 4
|
||||
|
||||
#endif /* _HCI_INTERNALS_H_ */
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define START_PACKET_BOUNDARY 2
|
||||
#define CONTINUATION_PACKET_BOUNDARY 1
|
||||
#define L2CAP_HEADER_SIZE 4
|
||||
#define L2CAP_LENGTH_SIZE 2
|
||||
|
||||
// TODO(zachoverflow): find good value for this
|
||||
#define NUMBER_OF_BUCKETS 42
|
||||
@@ -81,6 +82,11 @@ static void fragment_and_dispatch(BT_HDR *packet)
|
||||
callbacks->fragmented(packet, true);
|
||||
return;
|
||||
}
|
||||
if (packet->len < HCI_ACL_PREAMBLE_SIZE) {
|
||||
HCI_TRACE_ERROR("ACL packet too short for preamble (len=%u)", packet->len);
|
||||
callbacks->fragmented(packet, true);
|
||||
return;
|
||||
}
|
||||
|
||||
max_data_size =
|
||||
SUB_EVENT(packet->event) == LOCAL_BR_EDR_CONTROLLER_ID ?
|
||||
@@ -143,6 +149,11 @@ static void reassemble_and_dispatch(BT_HDR *packet)
|
||||
uint16_t l2cap_length;
|
||||
uint16_t acl_length __attribute__((unused));
|
||||
|
||||
if (packet->len < HCI_ACL_PREAMBLE_SIZE + L2CAP_LENGTH_SIZE) {
|
||||
HCI_TRACE_ERROR("ACL packet too short (len=%u)\n", packet->len);
|
||||
osi_free(packet);
|
||||
return;
|
||||
}
|
||||
STREAM_TO_UINT16(handle, stream);
|
||||
STREAM_TO_UINT16(acl_length, stream);
|
||||
STREAM_TO_UINT16(l2cap_length, stream);
|
||||
|
||||
@@ -106,46 +106,54 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
|
||||
|
||||
case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: /* 0x13 */
|
||||
case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: /* 0x15 */
|
||||
BE_STREAM_TO_UINT8 (p_result->get_cur_app_val.num_attr, p);
|
||||
if (len != (p_result->get_cur_app_val.num_attr + 1)) {
|
||||
if (len < 1) {
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
break;
|
||||
}
|
||||
p_u8 = p_result->get_cur_app_val.attrs;
|
||||
for (xx = 0, yy = 0; xx < p_result->get_cur_app_val.num_attr; xx++) {
|
||||
/* only report the valid player app attributes */
|
||||
if (AVRC_IsValidPlayerAttr(*p)) {
|
||||
p_u8[yy++] = *p;
|
||||
} else {
|
||||
BE_STREAM_TO_UINT8 (p_result->get_cur_app_val.num_attr, p);
|
||||
if (len != (p_result->get_cur_app_val.num_attr + 1)) {
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
break;
|
||||
}
|
||||
p_u8 = p_result->get_cur_app_val.attrs;
|
||||
for (xx = 0, yy = 0; xx < p_result->get_cur_app_val.num_attr; xx++) {
|
||||
/* only report the valid player app attributes */
|
||||
if (AVRC_IsValidPlayerAttr(*p)) {
|
||||
p_u8[yy++] = *p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p_result->get_cur_app_val.num_attr = yy;
|
||||
if (yy == 0) {
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
p_result->get_cur_app_val.num_attr = yy;
|
||||
if (yy == 0) {
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
}
|
||||
break;
|
||||
|
||||
case AVRC_PDU_SET_PLAYER_APP_VALUE: /* 0x14 */
|
||||
BE_STREAM_TO_UINT8 (p_result->set_app_val.num_val, p);
|
||||
size_needed = sizeof(tAVRC_APP_SETTING);
|
||||
if (p_buf && (len == ((p_result->set_app_val.num_val << 1) + 1))) {
|
||||
p_result->set_app_val.p_vals = (tAVRC_APP_SETTING *)p_buf;
|
||||
p_app_set = p_result->set_app_val.p_vals;
|
||||
for (xx = 0; ((xx < p_result->set_app_val.num_val) && (buf_len > size_needed)); xx++) {
|
||||
p_app_set[xx].attr_id = *p++;
|
||||
p_app_set[xx].attr_val = *p++;
|
||||
if (!avrc_is_valid_player_attrib_value(p_app_set[xx].attr_id, p_app_set[xx].attr_val)) {
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
}
|
||||
}
|
||||
if (xx != p_result->set_app_val.num_val) {
|
||||
AVRC_TRACE_ERROR("AVRC_PDU_SET_PLAYER_APP_VALUE not enough room:%d orig num_val:%d",
|
||||
xx, p_result->set_app_val.num_val);
|
||||
p_result->set_app_val.num_val = xx;
|
||||
}
|
||||
} else {
|
||||
AVRC_TRACE_ERROR("AVRC_PDU_SET_PLAYER_APP_VALUE NULL decode buffer or bad len");
|
||||
if (len < 1) {
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
} else {
|
||||
BE_STREAM_TO_UINT8 (p_result->set_app_val.num_val, p);
|
||||
size_needed = sizeof(tAVRC_APP_SETTING);
|
||||
if (p_buf && (len == ((p_result->set_app_val.num_val << 1) + 1))) {
|
||||
p_result->set_app_val.p_vals = (tAVRC_APP_SETTING *)p_buf;
|
||||
p_app_set = p_result->set_app_val.p_vals;
|
||||
for (xx = 0; ((xx < p_result->set_app_val.num_val) && (buf_len > size_needed)); xx++) {
|
||||
p_app_set[xx].attr_id = *p++;
|
||||
p_app_set[xx].attr_val = *p++;
|
||||
if (!avrc_is_valid_player_attrib_value(p_app_set[xx].attr_id, p_app_set[xx].attr_val)) {
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
}
|
||||
}
|
||||
if (xx != p_result->set_app_val.num_val) {
|
||||
AVRC_TRACE_ERROR("AVRC_PDU_SET_PLAYER_APP_VALUE not enough room:%d orig num_val:%d",
|
||||
xx, p_result->set_app_val.num_val);
|
||||
p_result->set_app_val.num_val = xx;
|
||||
}
|
||||
} else {
|
||||
AVRC_TRACE_ERROR("AVRC_PDU_SET_PLAYER_APP_VALUE NULL decode buffer or bad len");
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -118,6 +118,10 @@ void sdp_server_handle_client_req (tCONN_CB *p_ccb, BT_HDR *p_msg)
|
||||
UINT8 pdu_id;
|
||||
UINT16 trans_num, param_len;
|
||||
|
||||
if (p_msg->len < 5) {
|
||||
SDP_TRACE_WARNING("SDP - short request received: len=%u\n", p_msg->len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start inactivity timer */
|
||||
btu_start_timer (&p_ccb->timer_entry, BTU_TTYPE_SDP, SDP_INACT_TIMEOUT);
|
||||
@@ -187,6 +191,11 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_req + 2 > p_req_end) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_MAX_RECORDS_LIST);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the max replies we can send. Cap it at our max anyways. */
|
||||
BE_STREAM_TO_UINT16 (max_replies, p_req);
|
||||
|
||||
@@ -194,7 +203,6 @@ static void process_service_search (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
max_replies = SDP_MAX_RECORDS;
|
||||
}
|
||||
|
||||
|
||||
if ((!p_req) || (p_req > p_req_end)) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_REQ_SYNTAX, SDP_TEXT_BAD_MAX_RECORDS_LIST);
|
||||
return;
|
||||
@@ -322,14 +330,13 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
BOOLEAN is_cont = FALSE;
|
||||
UINT16 attr_len;
|
||||
|
||||
/* Extract the record handle */
|
||||
BE_STREAM_TO_UINT32 (rec_handle, p_req);
|
||||
|
||||
if (p_req > p_req_end) {
|
||||
if (p_req + 4 + 2 > p_req_end) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_SERV_REC_HDL, SDP_TEXT_BAD_HANDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Extract the record handle */
|
||||
BE_STREAM_TO_UINT32 (rec_handle, p_req);
|
||||
/* Get the max list length we can send. Cap it at MTU size minus overhead */
|
||||
BE_STREAM_TO_UINT16 (max_list_len, p_req);
|
||||
|
||||
@@ -371,7 +378,7 @@ static void process_service_attr_req (tCONN_CB *p_ccb, UINT16 trans_num,
|
||||
return;
|
||||
}
|
||||
|
||||
if (*p_req++ != SDP_CONTINUATION_LEN) {
|
||||
if ((*p_req++ != SDP_CONTINUATION_LEN) || (p_req + 2 > p_req_end)) {
|
||||
sdpu_build_n_send_error (p_ccb, trans_num, SDP_INVALID_CONT_STATE, SDP_TEXT_BAD_CONT_LEN);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -590,7 +590,7 @@ hci_driver_uart_dma_deinit(void)
|
||||
|
||||
ESP_ERROR_CHECK(uart_driver_delete(s_hci_driver_uart_dma_env.hci_uart_params->hci_uart_port));
|
||||
hci_driver_uart_dma_memory_deinit();
|
||||
if (!s_hci_driver_uart_dma_env.process_sem) {
|
||||
if (s_hci_driver_uart_dma_env.process_sem) {
|
||||
vSemaphoreDelete(s_hci_driver_uart_dma_env.process_sem);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user