Code: status_t NuPlayer::GenericSource::initFromDataSource() {
    sp<MediaExtractor> extractor;
 String8 mimeType;
 float confidence;
    sp<AMessage> dummy;
 bool isWidevineStreaming = false;

    CHECK(mDataSource != NULL);

 if (mIsWidevine) {
        isWidevineStreaming = SniffWVM(
                mDataSource, &mimeType, &confidence, &dummy);
 if (!isWidevineStreaming ||
                strcasecmp(
                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
            ALOGE("unsupported widevine mime: %s", mimeType.string());
 return UNKNOWN_ERROR;
 }
 } else if (mIsStreaming) {
 if (!mDataSource->sniff(&mimeType, &confidence, &dummy)) {
 return UNKNOWN_ERROR;
 }
        isWidevineStreaming = !strcasecmp(
                mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM);
 }

 if (isWidevineStreaming) {
        mCachedSource.clear();
        mDataSource = mHttpSource;
        mWVMExtractor = new WVMExtractor(mDataSource);
        mWVMExtractor->setAdaptiveStreamingMode(true);
 if (mUIDValid) {
            mWVMExtractor->setUID(mUID);
 }
        extractor = mWVMExtractor;
 } else {
        extractor = MediaExtractor::Create(mDataSource,
                mimeType.isEmpty() ? NULL : mimeType.string());
 }

 if (extractor == NULL) {
 return UNKNOWN_ERROR;
 }

 if (extractor->getDrmFlag()) {
        checkDrmStatus(mDataSource);
 }

    mFileMeta = extractor->getMetaData();
 if (mFileMeta != NULL) {
 int64_t duration;
 if (mFileMeta->findInt64(kKeyDuration, &duration)) {
            mDurationUs = duration;
 }

 if (!mIsWidevine) {
 const char *fileMime;
 if (mFileMeta->findCString(kKeyMIMEType, &fileMime)
 && !strncasecmp(fileMime, "video/wvm", 9)) {
                mIsWidevine = true;
 }
 }
 }

 int32_t totalBitrate = 0;

 size_t numtracks = extractor->countTracks();
 if (numtracks == 0) {
 return UNKNOWN_ERROR;
 }

 
     for (size_t i = 0; i < numtracks; ++i) {
         sp<MediaSource> track = extractor->getTrack(i);
 
         sp<MetaData> meta = extractor->getTrackMetaData(i);
 
 const char *mime;
        CHECK(meta->findCString(kKeyMIMEType, &mime));

 if (!strncasecmp(mime, "audio/", 6)) {
 if (mAudioTrack.mSource == NULL) {
                mAudioTrack.mIndex = i;
                mAudioTrack.mSource = track;
                mAudioTrack.mPackets =
 new AnotherPacketSource(mAudioTrack.mSource->getFormat());

 if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
                    mAudioIsVorbis = true;
 } else {
                    mAudioIsVorbis = false;
 }
 }
 } else if (!strncasecmp(mime, "video/", 6)) {
 if (mVideoTrack.mSource == NULL) {
                mVideoTrack.mIndex = i;
                mVideoTrack.mSource = track;
                mVideoTrack.mPackets =
 new AnotherPacketSource(mVideoTrack.mSource->getFormat());

 int32_t secure;
 if (meta->findInt32(kKeyRequiresSecureBuffers, &secure)
 && secure) {
                    mIsSecure = true;
 if (mUIDValid) {
                        extractor->setUID(mUID);
 }
 }

             }
         }
 
        if (track != NULL) {
            mSources.push(track);
            int64_t durationUs;
            if (meta->findInt64(kKeyDuration, &durationUs)) {
                if (durationUs > mDurationUs) {
                    mDurationUs = durationUs;
                }
            }
            int32_t bitrate;
            if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) {
                totalBitrate += bitrate;
            } else {
                totalBitrate = -1;
             }
         }
     }
 
     mBitrate = totalBitrate;

 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)
