Bug 1204580 - p2: Check box ranges. r=rillian
authorGerald Squelart <gsquelart@mozilla.com>
Fri, 02 Oct 2015 09:20:39 +0200
changeset 265615 35958f485b2987e8b54fa3e66500174ba5cda867
parent 265614 0f18e328113b444de6b8002e621250ab0170fef7
child 265616 c3ac8787049490102c9df6dc32245a8c5add8c0a
push id65995
push usercbook@mozilla.com
push dateFri, 02 Oct 2015 07:21:50 +0000
treeherdermozilla-inbound@35958f485b29 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian
bugs1204580
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1204580 - p2: Check box ranges. r=rillian
media/libstagefright/binding/Box.cpp
--- a/media/libstagefright/binding/Box.cpp
+++ b/media/libstagefright/binding/Box.cpp
@@ -35,16 +35,21 @@ BoxOffset(AtomType aType)
 
   return 0;
 }
 
 Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent)
   : mContext(aContext), mParent(aParent)
 {
   uint8_t header[8];
+
+  if (aOffset > INT64_MAX - sizeof(header)) {
+    return;
+  }
+
   MediaByteRange headerRange(aOffset, aOffset + sizeof(header));
   if (mParent && !mParent->mRange.Contains(headerRange)) {
     return;
   }
 
   const MediaByteRange* byteRange;
   for (int i = 0; ; i++) {
     if (i == mContext->mByteRanges.Length()) {
@@ -62,39 +67,51 @@ Box::Box(BoxContext* aContext, uint64_t 
                                        &bytes) ||
       bytes != sizeof(header)) {
     return;
   }
 
   uint64_t size = BigEndian::readUint32(header);
   if (size == 1) {
     uint8_t bigLength[8];
+    if (aOffset > INT64_MAX - sizeof(header) - sizeof(bigLength)) {
+      return;
+    }
     MediaByteRange bigLengthRange(headerRange.mEnd,
                                   headerRange.mEnd + sizeof(bigLength));
     if ((mParent && !mParent->mRange.Contains(bigLengthRange)) ||
         !byteRange->Contains(bigLengthRange) ||
-        !mContext->mSource->CachedReadAt(aOffset + 8, bigLength,
+        !mContext->mSource->CachedReadAt(aOffset + sizeof(header), bigLength,
                                          sizeof(bigLength), &bytes) ||
         bytes != sizeof(bigLength)) {
       return;
     }
     size = BigEndian::readUint64(bigLength);
     mBodyOffset = bigLengthRange.mEnd;
   } else if (size == 0) {
     // box extends to end of file.
     size = mContext->mByteRanges.LastElement().mEnd - aOffset;
     mBodyOffset = headerRange.mEnd;
   } else {
     mBodyOffset = headerRange.mEnd;
   }
 
+  if (size > INT64_MAX) {
+    return;
+  }
+  int64_t end = static_cast<int64_t>(aOffset) + static_cast<int64_t>(size);
+  if (end < static_cast<int64_t>(aOffset)) {
+    // Overflowed.
+    return;
+  }
+
   mType = BigEndian::readUint32(&header[4]);
   mChildOffset = mBodyOffset + BoxOffset(mType);
 
-  MediaByteRange boxRange(aOffset, aOffset + size);
+  MediaByteRange boxRange(aOffset, end);
   if (mChildOffset > boxRange.mEnd ||
       (mParent && !mParent->mRange.Contains(boxRange)) ||
       !byteRange->Contains(boxRange)) {
     return;
   }
 
   mRange = boxRange;
 }