Merge branch 'bugfix/oob_read_in_continue_packet_v6.0' into 'release/v6.0'

fix(bt/bluedroid): fix ACL reassembly dropping valid continuation fragments (v6.0)

See merge request espressif/esp-idf!47378
This commit is contained in:
Jiang Jiang Jian
2026-04-09 14:36:57 +08:00
@@ -149,14 +149,15 @@ 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) {
/* All ACL packets need at least the 4-byte HCI ACL preamble (handle + length) */
if (packet->len < HCI_ACL_PREAMBLE_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);
assert(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE);
@@ -172,6 +173,14 @@ static void reassemble_and_dispatch(BT_HDR *packet)
osi_free(partial_packet);
}
/* START packets must also contain the L2CAP header (length field) */
if (packet->len < HCI_ACL_PREAMBLE_SIZE + L2CAP_LENGTH_SIZE) {
HCI_TRACE_ERROR("ACL START packet too short for L2CAP header (len=%u)\n", packet->len);
osi_free(packet);
return;
}
STREAM_TO_UINT16(l2cap_length, stream);
/* 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);