Bug 1121757: Prevent out of bound memory access should AVC data be invalid. r=kinetik a=sledru
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 16 Jan 2015 20:27:11 +1100
changeset 249250 d8aa7a97c32540c3ab5f40c8a34880f466ce86bc
parent 249249 486b783c09b6f4aab4b4b8b5cffc42ec9b865650
child 249251 223b55babd02eb1cfb4739470e0d80dcedfbc4b1
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik, sledru
bugs1121757
milestone37.0a2
Bug 1121757: Prevent out of bound memory access should AVC data be invalid. r=kinetik a=sledru
media/libstagefright/binding/AnnexB.cpp
--- a/media/libstagefright/binding/AnnexB.cpp
+++ b/media/libstagefright/binding/AnnexB.cpp
@@ -23,24 +23,39 @@ AnnexB::ConvertSampleToAnnexB(MP4Sample*
 
   if (!IsAVCC(aSample)) {
     return;
   }
   MOZ_ASSERT(aSample->data);
 
   ConvertSampleTo4BytesAVCC(aSample);
 
-  uint8_t* d = aSample->data;
-  while (d + 4 < aSample->data + aSample->size) {
-    uint32_t nalLen = mozilla::BigEndian::readUint32(d);
-    // Overwrite the NAL length with the Annex B separator.
-    memcpy(d, kAnnexBDelimiter, ArrayLength(kAnnexBDelimiter));
-    d += 4 + nalLen;
+  if (aSample->size < 4) {
+    // Nothing to do, it's corrupted anyway.
+    return;
   }
 
+  ByteReader reader(aSample->data, aSample->size);
+
+  mozilla::Vector<uint8_t> tmp;
+  ByteWriter writer(tmp);
+
+  while (reader.Remaining() >= 4) {
+    uint32_t nalLen = reader.ReadU32();
+    const uint8_t* p = reader.Read(nalLen);
+
+    writer.Write(kAnnexBDelimiter, ArrayLength(kAnnexBDelimiter));
+    if (!p) {
+      break;
+    }
+    writer.Write(p, nalLen);
+  }
+
+  aSample->Replace(tmp.begin(), tmp.length());
+
   // Prepend the Annex B NAL with SPS and PPS tables to keyframes.
   if (aSample->is_sync_point) {
     nsRefPtr<ByteBuffer> annexB =
       ConvertExtraDataToAnnexB(aSample->extra_data);
     aSample->Prepend(annexB->Elements(), annexB->Length());
   }
 }