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 242898 84bf56da4a55
parent 242897 64d25509541e
child 242899 7a8d1dd9fff3
push id4333
push userrgiles@mozilla.com
push date2015-01-17 17:47 +0000
treeherdermozilla-beta@dfbca180664d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik, sledru
bugs1121757
milestone36.0
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());
   }
 }