Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2c74a3cd authored by Wonsik Kim's avatar Wonsik Kim
Browse files

stagefright: fix integer overflow error

Bug: 30103394
Change-Id: If449d3e30a0bf2ebea5317f41813bfed094f7408
parent a4c20889
Loading
Loading
Loading
Loading
+14 −13
Original line number Original line Diff line number Diff line
@@ -18,6 +18,8 @@
//#define LOG_NDEBUG 0
//#define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/Log.h>


#include <limits>

#include "include/SampleTable.h"
#include "include/SampleTable.h"
#include "include/SampleIterator.h"
#include "include/SampleIterator.h"


@@ -45,6 +47,8 @@ const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


const off64_t kMaxOffset = std::numeric_limits<off64_t>::max();

struct SampleTable::CompositionDeltaLookup {
struct SampleTable::CompositionDeltaLookup {
    CompositionDeltaLookup();
    CompositionDeltaLookup();


@@ -238,11 +242,11 @@ status_t SampleTable::setSampleToChunkParams(


    mNumSampleToChunkOffsets = U32_AT(&header[4]);
    mNumSampleToChunkOffsets = U32_AT(&header[4]);


    if ((data_size - 8) / 12 < mNumSampleToChunkOffsets) {
    if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) {
        return ERROR_MALFORMED;
        return ERROR_MALFORMED;
    }
    }


    if ((uint64_t)SIZE_MAX / sizeof(SampleToChunkEntry) <=
    if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <=
            (uint64_t)mNumSampleToChunkOffsets) {
            (uint64_t)mNumSampleToChunkOffsets) {
        ALOGE("Sample-to-chunk table size too large.");
        ALOGE("Sample-to-chunk table size too large.");
        return ERROR_OUT_OF_RANGE;
        return ERROR_OUT_OF_RANGE;
@@ -274,21 +278,19 @@ status_t SampleTable::setSampleToChunkParams(
        return OK;
        return OK;
    }
    }


    if ((off64_t)(SIZE_MAX - 8 -
    if ((off64_t)(kMaxOffset - 8 -
            ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry)))
            ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry)))
            < mSampleToChunkOffset) {
            < mSampleToChunkOffset) {
        return ERROR_MALFORMED;
        return ERROR_MALFORMED;
    }
    }


    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
        uint8_t buffer[12];
        uint8_t buffer[sizeof(SampleToChunkEntry)];

        if ((SIZE_MAX - 8 - (i * 12)) < (size_t)mSampleToChunkOffset) {
            return ERROR_MALFORMED;
        }


        if (mDataSource->readAt(
        if (mDataSource->readAt(
                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
                    mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry),
                    buffer,
                    sizeof(buffer))
                != (ssize_t)sizeof(buffer)) {
                != (ssize_t)sizeof(buffer)) {
            return ERROR_IO;
            return ERROR_IO;
        }
        }
@@ -389,8 +391,7 @@ status_t SampleTable::setTimeToSampleParams(
    }
    }


    mTimeToSampleCount = U32_AT(&header[4]);
    mTimeToSampleCount = U32_AT(&header[4]);
    if ((uint64_t)mTimeToSampleCount >
    if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
        (uint64_t)UINT32_MAX / (2 * sizeof(uint32_t))) {
        // Choose this bound because
        // Choose this bound because
        // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
        // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
        //    time-to-sample entry in the time-to-sample table.
        //    time-to-sample entry in the time-to-sample table.
@@ -474,7 +475,7 @@ status_t SampleTable::setCompositionTimeToSampleParams(


    mNumCompositionTimeDeltaEntries = numEntries;
    mNumCompositionTimeDeltaEntries = numEntries;
    uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(int32_t);
    uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(int32_t);
    if (allocSize > SIZE_MAX) {
    if (allocSize > kMaxTotalSize) {
        ALOGE("Composition-time-to-sample table size too large.");
        ALOGE("Composition-time-to-sample table size too large.");
        return ERROR_OUT_OF_RANGE;
        return ERROR_OUT_OF_RANGE;
    }
    }
@@ -541,7 +542,7 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size)
    }
    }


    uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t);
    uint64_t allocSize = (uint64_t)mNumSyncSamples * sizeof(uint32_t);
    if (allocSize > SIZE_MAX) {
    if (allocSize > kMaxTotalSize) {
        ALOGE("Sync sample table size too large.");
        ALOGE("Sync sample table size too large.");
        return ERROR_OUT_OF_RANGE;
        return ERROR_OUT_OF_RANGE;
    }
    }