Bug 1232069 - Check box sizes before alloc&copy. r=jya, a=ritu
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 29 Dec 2015 13:12:14 -0500
changeset 305925 4873d8df4a8761bee403d462af6bacd4efd85a94
parent 305924 519bc75be6d2fc4c7a4e23e4284af01f83dcd95d
child 305926 97c79bd9b8b93ced0c6ee148568c91d37c762dd0
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya, ritu
bugs1232069
milestone44.0
Bug 1232069 - Check box sizes before alloc&copy. r=jya, a=ritu
media/libstagefright/binding/Box.cpp
media/libstagefright/binding/MoofParser.cpp
media/libstagefright/binding/include/mp4_demuxer/Box.h
--- a/media/libstagefright/binding/Box.cpp
+++ b/media/libstagefright/binding/Box.cpp
@@ -8,16 +8,20 @@
 #include "mp4_demuxer/Stream.h"
 #include "mozilla/Endian.h"
 #include <algorithm>
 
 using namespace mozilla;
 
 namespace mp4_demuxer {
 
+// Limit reads to 32MiB max.
+// static
+const uint64_t Box::kMAX_BOX_READ = 32 * 1024 * 1024;
+
 // Returns the offset from the start of the body of a box of type |aType|
 // to the start of its first child.
 static uint32_t
 BoxOffset(AtomType aType)
 {
   const uint32_t FULLBOX_OFFSET = 4;
 
   if (aType == AtomType("mp4a") || aType == AtomType("enca")) {
@@ -144,18 +148,18 @@ Box::Read(nsTArray<uint8_t>* aDest)
 }
 
 bool
 Box::Read(nsTArray<uint8_t>* aDest, const MediaByteRange& aRange)
 {
   int64_t length;
   if (!mContext->mSource->Length(&length)) {
     // The HTTP server didn't give us a length to work with.
-    // Limit the read to 32MiB max.
-    length = std::min(aRange.mEnd - mChildOffset, uint64_t(32 * 1024 * 1024));
+    // Limit the read to kMAX_BOX_READ max.
+    length = std::min(aRange.mEnd - mChildOffset, kMAX_BOX_READ);
   } else {
     length = aRange.mEnd - mChildOffset;
   }
   aDest->SetLength(length);
   size_t bytes;
   if (!mContext->mSource->CachedReadAt(mChildOffset, aDest->Elements(),
                                        aDest->Length(), &bytes) ||
       bytes != aDest->Length()) {
--- a/media/libstagefright/binding/MoofParser.cpp
+++ b/media/libstagefright/binding/MoofParser.cpp
@@ -177,17 +177,19 @@ MoofParser::HasMetadata()
 }
 
 already_AddRefed<mozilla::MediaByteBuffer>
 MoofParser::Metadata()
 {
   MediaByteRange ftyp;
   MediaByteRange moov;
   ScanForMetadata(ftyp, moov);
-  if (!ftyp.Length() || !moov.Length()) {
+  if (!ftyp.Length() || !moov.Length() ||
+      ftyp.Length() > Box::kMAX_BOX_READ || moov.Length() > Box::kMAX_BOX_READ) {
+    // No ftyp or moov, or trying to read bigger-that-readable box (32MB).
     return nullptr;
   }
   RefPtr<MediaByteBuffer> metadata = new MediaByteBuffer();
   if (!metadata->SetLength(ftyp.Length() + moov.Length(), fallible)) {
     // OOM
     return nullptr;
   }
 
--- a/media/libstagefright/binding/include/mp4_demuxer/Box.h
+++ b/media/libstagefright/binding/include/mp4_demuxer/Box.h
@@ -46,16 +46,18 @@ public:
   const Box* Parent() const { return mParent; }
   bool IsType(const char* aType) const { return mType == AtomType(aType); }
 
   Box Next() const;
   Box FirstChild() const;
   bool Read(nsTArray<uint8_t>* aDest);
   bool Read(nsTArray<uint8_t>* aDest, const MediaByteRange& aRange);
 
+  static const uint64_t kMAX_BOX_READ;
+
 private:
   bool Contains(MediaByteRange aRange) const;
   BoxContext* mContext;
   mozilla::MediaByteRange mRange;
   uint64_t mBodyOffset;
   uint64_t mChildOffset;
   AtomType mType;
   const Box* mParent;