Bug 1149605: Avoid potential integers overflow. r=kentuckyfriedtakahe
☠☠ backed out by 3c1bfc5258c9 ☠ ☠
authorJean-Yves Avenard <jyavenard@mozilla.com>
Tue, 28 Apr 2015 22:28:41 +1000
changeset 241439 87277085561a1e6f2de159dfb9784e1ff1257652
parent 241438 1b04bf62185810297d444bbbee13c8870e370f63
child 241440 abdd5415502397ae44219c86eecee4741e4c7133
push id28661
push userryanvm@gmail.com
push dateTue, 28 Apr 2015 19:32:03 +0000
treeherdermozilla-central@4de411d0cf38 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskentuckyfriedtakahe
bugs1149605
milestone40.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 1149605: Avoid potential integers overflow. r=kentuckyfriedtakahe
media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
--- a/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/SampleTable.cpp
@@ -200,21 +200,21 @@ status_t SampleTable::setChunkOffsetPara
     if (U32_AT(header) != 0) {
         // Expected version = 0, flags = 0.
         return ERROR_MALFORMED;
     }
 
     mNumChunkOffsets = U32_AT(&header[4]);
 
     if (mChunkOffsetType == kChunkOffsetType32) {
-        if (data_size < 8 + mNumChunkOffsets * 4) {
+        if (data_size < 8 + (uint64_t)mNumChunkOffsets * 4) {
             return ERROR_MALFORMED;
         }
     } else {
-        if (data_size < 8 + mNumChunkOffsets * 8) {
+        if (data_size < 8 + (uint64_t)mNumChunkOffsets * 8) {
             return ERROR_MALFORMED;
         }
     }
 
     return OK;
 }
 
 status_t SampleTable::setSampleToChunkParams(
@@ -237,17 +237,17 @@ status_t SampleTable::setSampleToChunkPa
 
     if (U32_AT(header) != 0) {
         // Expected version = 0, flags = 0.
         return ERROR_MALFORMED;
     }
 
     mNumSampleToChunkOffsets = U32_AT(&header[4]);
 
-    if (data_size < 8 + mNumSampleToChunkOffsets * 12) {
+    if (data_size < 8 + (uint64_t)mNumSampleToChunkOffsets * 12) {
         return ERROR_MALFORMED;
     }
 
     mSampleToChunkEntries =
         new SampleToChunkEntry[mNumSampleToChunkOffsets];
 
     for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
         uint8_t buffer[12];
@@ -301,34 +301,34 @@ status_t SampleTable::setSampleSizeParam
 
     if (type == kSampleSizeType32) {
         mSampleSizeFieldSize = 32;
 
         if (mDefaultSampleSize != 0) {
             return OK;
         }
 
-        if (data_size < 12 + mNumSampleSizes * 4) {
+        if (data_size < 12 + (uint64_t)mNumSampleSizes * 4) {
             return ERROR_MALFORMED;
         }
     } else {
         if ((mDefaultSampleSize & 0xffffff00) != 0) {
             // The high 24 bits are reserved and must be 0.
             return ERROR_MALFORMED;
         }
 
         mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
         mDefaultSampleSize = 0;
 
         if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
             && mSampleSizeFieldSize != 16) {
             return ERROR_MALFORMED;
         }
 
-        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
+        if (data_size < 12 + ((uint64_t)mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
             return ERROR_MALFORMED;
         }
     }
 
     return OK;
 }
 
 status_t SampleTable::setTimeToSampleParams(
@@ -344,16 +344,20 @@ status_t SampleTable::setTimeToSamplePar
     }
 
     if (U32_AT(header) != 0) {
         // Expected version = 0, flags = 0.
         return ERROR_MALFORMED;
     }
 
     mTimeToSampleCount = U32_AT(&header[4]);
+    if (mTimeToSampleCount > (size_t)-1 / 2 / sizeof(uint32_t)) {
+        // Avoid later overflow.
+        return ERROR_MALFORMED;
+    }
     mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
 
     size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
     if (mDataSource->readAt(
                 data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
         return ERROR_IO;
     }
 
@@ -381,17 +385,17 @@ status_t SampleTable::setCompositionTime
 
     if (U32_AT(header) != 0) {
         // Expected version = 0, flags = 0.
         return ERROR_MALFORMED;
     }
 
     size_t numEntries = U32_AT(&header[4]);
 
-    if (data_size != (numEntries + 1) * 8) {
+    if (data_size != ((uint64_t)numEntries + 1) * 8) {
         return ERROR_MALFORMED;
     }
 
     mNumCompositionTimeDeltaEntries = numEntries;
     mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
 
     if (mDataSource->readAt(
                 data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
@@ -426,16 +430,20 @@ status_t SampleTable::setSyncSampleParam
     }
 
     if (U32_AT(header) != 0) {
         // Expected version = 0, flags = 0.
         return ERROR_MALFORMED;
     }
 
     mNumSyncSamples = U32_AT(&header[4]);
+    if (mNumSyncSamples > (size_t)-1 / sizeof(uint32_t)) {
+        // Avoid later overflow.
+        return ERROR_MALFORMED;
+    }
 
     if (mNumSyncSamples < 2) {
         ALOGV("Table of sync samples is empty or has only a single entry!");
     }
 
     mSyncSamples = new uint32_t[mNumSyncSamples];
     size_t size = mNumSyncSamples * sizeof(uint32_t);
     if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
@@ -602,16 +610,21 @@ SampleTable::parseSampleCencInfo() {
         return OK;
     }
 
     if (!mCencSizes.isEmpty() && mCencOffsets.size() > 1 &&
         mCencSizes.size() != mCencOffsets.size()) {
         return ERROR_MALFORMED;
     }
 
+    if (mCencInfoCount > (size_t)-1 / sizeof(SampleCencInfo)) {
+        // Avoid future OOM.
+        return ERROR_MALFORMED;
+    }
+
     mCencInfo = new SampleCencInfo[mCencInfoCount];
     for (uint32_t i = 0; i < mCencInfoCount; i++) {
         mCencInfo[i].mSubsamples = NULL;
     }
 
     uint64_t nextOffset = mCencOffsets[0];
     for (uint32_t i = 0; i < mCencInfoCount; i++) {
         uint8_t size = mCencDefaultSize ? mCencDefaultSize : mCencSizes[i];