Commit message: None
CVE: CVE-2017-0813
CWE: CWE-772
Vulnerability description: A denial of service vulnerability in the Android media framework (libstagefright). Product: Android. Versions: 7.0, 7.1.1, 7.1.2. Android ID: A-36531046.

Project: Android

void SampleTable::buildSampleEntriesTable() {
 Mutex::Autolock autoLock(mLock);

 if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
 if (mNumSampleSizes == 0) {
            ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
 }
 return;
 }

    mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry);
 if (mTotalSize > kMaxTotalSize) {
        ALOGE("Sample entry table size would make sample table too large.\n"
 "    Requested sample entry table size = %llu\n"
 "    Eventual sample table size >= %llu\n"
 "    Allowed sample table size = %llu\n",
 (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry),
 (unsigned long long)mTotalSize,
 (unsigned long long)kMaxTotalSize);
 return;
 }

    mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
 if (!mSampleTimeEntries) {
        ALOGE("Cannot allocate sample entry table with %llu entries.",
 (unsigned long long)mNumSampleSizes);
 return;
 }

 uint32_t sampleIndex = 0;
 uint32_t sampleTime = 0;

 for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
 uint32_t n = mTimeToSample[2 * i];
 uint32_t delta = mTimeToSample[2 * i + 1];

 for (uint32_t j = 0; j < n; ++j) {
 if (sampleIndex < mNumSampleSizes) {

                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;

 int32_t compTimeDelta =
                    mCompositionDeltaLookup->getCompositionTimeOffset(
                            sampleIndex);

 if ((compTimeDelta < 0 && sampleTime <
 (compTimeDelta == INT32_MIN ?
                                INT32_MAX : uint32_t(-compTimeDelta)))
 || (compTimeDelta > 0 &&
                                sampleTime > UINT32_MAX - compTimeDelta)) {
                    ALOGE("%u + %d would overflow, clamping",
                            sampleTime, compTimeDelta);
 if (compTimeDelta < 0) {
                        sampleTime = 0;
 } else {
                        sampleTime = UINT32_MAX;
 }
                    compTimeDelta = 0;
 }

                mSampleTimeEntries[sampleIndex].mCompositionTime =
                        compTimeDelta > 0 ? sampleTime + compTimeDelta:
                                sampleTime - (-compTimeDelta);
 }

 ++sampleIndex;
            sampleTime += delta;
 }
 }

    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
 CompareIncreasingTime);
}

Project: Android

status_t SampleTable::setTimeToSampleParams(
 off64_t data_offset, size_t data_size) {
 if (mHasTimeToSample || data_size < 8) {
 return ERROR_MALFORMED;
 }

 uint8_t header[8];
 if (mDataSource->readAt(
                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
 return ERROR_IO;
 }

 if (U32_AT(header) != 0) {
 return ERROR_MALFORMED;
 }

    mTimeToSampleCount = U32_AT(&header[4]);
 if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
        ALOGE("Time-to-sample table size too large.");
 return ERROR_OUT_OF_RANGE;
 }


 uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
    mTotalSize += allocSize;
 if (mTotalSize > kMaxTotalSize) {
        ALOGE("Time-to-sample table size would make sample table too large.\n"
 "    Requested time-to-sample table size = %llu\n"
 "    Eventual sample table size >= %llu\n"
 "    Allowed sample table size = %llu\n",
 (unsigned long long)allocSize,
 (unsigned long long)mTotalSize,
 (unsigned long long)kMaxTotalSize);
 return ERROR_OUT_OF_RANGE;
 }

    mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
 if (!mTimeToSample) {
        ALOGE("Cannot allocate time-to-sample table with %llu entries.",
 (unsigned long long)mTimeToSampleCount);
 return ERROR_OUT_OF_RANGE;
 }

 if (mDataSource->readAt(data_offset + 8, mTimeToSample,
 (size_t)allocSize) < (ssize_t)allocSize) {
        ALOGE("Incomplete data read for time-to-sample table.");
 return ERROR_IO;
 }

 for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) {
        mTimeToSample[i] = ntohl(mTimeToSample[i]);
 }

    mHasTimeToSample = true;
 return OK;
}