Code: status_t SampleIterator::seekTo(uint32_t sampleIndex) {
    ALOGV("seekTo(%d)", sampleIndex);

 if (sampleIndex >= mTable->mNumSampleSizes) {
 return ERROR_END_OF_STREAM;
 }

 if (mTable->mSampleToChunkOffset < 0
 || mTable->mChunkOffsetOffset < 0
 || mTable->mSampleSizeOffset < 0
 || mTable->mTimeToSampleCount == 0) {

 return ERROR_MALFORMED;
 }

 if (mInitialized && mCurrentSampleIndex == sampleIndex) {
 return OK;
 }

 if (!mInitialized || sampleIndex < mFirstChunkSampleIndex) {
        reset();
 }

 if (sampleIndex >= mStopChunkSampleIndex) {
 status_t err;
 if ((err = findChunkRange(sampleIndex)) != OK) {
            ALOGE("findChunkRange failed");
 return err;
 }
 }

 
     CHECK(sampleIndex < mStopChunkSampleIndex);
 
     uint32_t chunk =
         (sampleIndex - mFirstChunkSampleIndex) / mSamplesPerChunk
         + mFirstChunk;

 if (!mInitialized || chunk != mCurrentChunkIndex) {
        mCurrentChunkIndex = chunk;

 status_t err;
 if ((err = getChunkOffset(chunk, &mCurrentChunkOffset)) != OK) {
            ALOGE("getChunkOffset return error");
 return err;
 }

        mCurrentChunkSampleSizes.clear();

 uint32_t firstChunkSampleIndex =
            mFirstChunkSampleIndex
 + mSamplesPerChunk * (mCurrentChunkIndex - mFirstChunk);

 for (uint32_t i = 0; i < mSamplesPerChunk; ++i) {
 size_t sampleSize;
 if ((err = getSampleSizeDirect(
                            firstChunkSampleIndex + i, &sampleSize)) != OK) {
                ALOGE("getSampleSizeDirect return error");
 return err;
 }

            mCurrentChunkSampleSizes.push(sampleSize);
 }
 }

 uint32_t chunkRelativeSampleIndex =
 (sampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk;

    mCurrentSampleOffset = mCurrentChunkOffset;
 for (uint32_t i = 0; i < chunkRelativeSampleIndex; ++i) {
        mCurrentSampleOffset += mCurrentChunkSampleSizes[i];
 }

    mCurrentSampleSize = mCurrentChunkSampleSizes[chunkRelativeSampleIndex];
 if (sampleIndex < mTTSSampleIndex) {
        mTimeToSampleIndex = 0;
        mTTSSampleIndex = 0;
        mTTSSampleTime = 0;
        mTTSCount = 0;
        mTTSDuration = 0;
 }

 status_t err;
 if ((err = findSampleTimeAndDuration(
            sampleIndex, &mCurrentSampleTime, &mCurrentSampleDuration)) != OK) {
        ALOGE("findSampleTime return error");
 return err;
 }

    mCurrentSampleIndex = sampleIndex;

    mInitialized = true;

 return OK;
}

Vulnerability Type: DoS Exec Code Overflow Mem. Corr. 
CWE ID: CWE-119
Summary: media/libmediaplayerservice/nuplayer/GenericSource.cpp in mediaserver in Android 4.x before 4.4.4, 5.0.x before 5.0.2, 5.1.x before 5.1.1, and 6.x before 2016-07-01 does not validate certain track data, which allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via a crafted media file, aka internal bug 28799341.
Commit Message: MPEG4Extractor: ensure kKeyTrackID exists before creating an MPEG4Source as track.

GenericSource: return error when no track exists.

SampleIterator: make sure mSamplesPerChunk is not zero before using it as divisor.

Bug: 21657957
Bug: 23705695
Bug: 22802344
Bug: 28799341
Change-Id: I7664992ade90b935d3f255dcd43ecc2898f30b04
(cherry picked from commit 0386c91b8a910a134e5898ffa924c1b6c7560b13)
