fix(bt): enhanced packet length check for HCI module
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user