OSDN Git Service

Fix potential buffer overflow and uninitialized read in reassemble_and_dispatch_iso
authorJakub Pawlowski <jpawlowski@google.com>
Thu, 10 Jun 2021 20:01:32 +0000 (22:01 +0200)
committerJakub Pawlowski <jpawlowski@google.com>
Fri, 25 Jun 2021 13:11:00 +0000 (15:11 +0200)
Tag: #security
Test: compilation
Bug: 188673156
Change-Id: Id9f2acfde05da681c82adc25d602cc48a2bc5df9

hci/src/packet_fragmenter.cc

index ca71e92..a7074d5 100644 (file)
@@ -254,8 +254,10 @@ static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) {
         return;
       }
 
-      if ((boundary_flag == HCI_ISO_BF_COMPLETE_PACKET) &&
-          (iso_full_len != packet->len)) {
+      if (((boundary_flag == HCI_ISO_BF_COMPLETE_PACKET) &&
+           (iso_full_len != packet->len)) ||
+          ((boundary_flag == HCI_ISO_BF_FIRST_FRAGMENTED_PACKET) &&
+           (iso_full_len <= packet->len))) {
         LOG_ERROR("%s corrupted ISO frame", __func__);
         return;
       }
@@ -324,6 +326,18 @@ static void reassemble_and_dispatch_iso(UNUSED_ATTR BT_HDR* packet) {
         return;
       }
 
+      if (partial_packet->len !=
+          partial_packet->offset + packet->len - HCI_ISO_PREAMBLE_SIZE) {
+        LOG_ERROR(
+            "%s got last fragment, but it doesn't fill up the whole packet of "
+            "size %d",
+            __func__, partial_packet->len);
+        buffer_allocator->free(packet);
+        partial_iso_packets.erase(map_iter);
+        buffer_allocator->free(partial_packet);
+        return;
+      }
+
       partial_packet->layer_specific |= BT_ISO_HDR_OFFSET_POINTS_DATA;
       partial_packet->offset = HCI_ISO_PREAMBLE_SIZE;
       if (partial_packet->layer_specific & BT_ISO_HDR_CONTAINS_TS)