fix(ble/bluedroid): Fix potential CVE-2020-0022 in reassemble_and_dispatch

- Reference: https://nvd.nist.gov/vuln/detail/CVE-2020-0022


(cherry picked from commit 1f7fd91b5a)

Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
This commit is contained in:
Zhang Hai Peng
2025-12-02 00:04:40 +08:00
committed by BLE BOT
parent 64726df15e
commit e3f03bb165
@@ -161,6 +161,13 @@ static void reassemble_and_dispatch(BT_HDR *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;
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->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;
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);