diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp index 7f4773bd47..09ad6b278b 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerCCDecoder.cpp @@ -316,6 +316,11 @@ bool NuPlayer::CCDecoder::extractFromMPEGUserData(const sp &accessUnit) const size_t *userData = (size_t *)mpegUserData->data(); for (size_t i = 0; i < mpegUserData->size() / sizeof(size_t); ++i) { + if (accessUnit->size() < userData[i]) { + ALOGW("b/129068792, skip invalid offset for user data"); + android_errorWriteLog(0x534e4554, "129068792"); + continue; + } trackAdded |= parseMPEGUserDataUnit( timeUs, accessUnit->data() + userData[i], accessUnit->size() - userData[i]); } @@ -325,6 +330,12 @@ bool NuPlayer::CCDecoder::extractFromMPEGUserData(const sp &accessUnit) // returns true if a new CC track is found bool NuPlayer::CCDecoder::parseMPEGUserDataUnit(int64_t timeUs, const uint8_t *data, size_t size) { + if (size < 9) { + ALOGW("b/129068792, MPEG user data size too small %zu", size); + android_errorWriteLog(0x534e4554, "129068792"); + return false; + } + ABitReader br(data + 4, 5); uint32_t user_identifier = br.getBits(32); @@ -377,8 +388,14 @@ bool NuPlayer::CCDecoder::parseMPEGCCData(int64_t timeUs, const uint8_t *data, s mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2); br.skipBits(16); } else if (mDTVCCPacket->size() > 0 && cc_type == 2) { - memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2); - mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2); + if (mDTVCCPacket->capacity() - mDTVCCPacket->size() >= 2) { + memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2); + mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2); + } else { + ALOGW("b/129068792, skip CC due to too much data(%zu, %zu)", + mDTVCCPacket->capacity(), mDTVCCPacket->size()); + android_errorWriteLog(0x534e4554, "129068792"); + } br.skipBits(16); } else if (cc_type == 0 || cc_type == 1) { uint8_t cc_data_1 = br.getBits(8) & 0x7f; @@ -465,6 +482,11 @@ bool NuPlayer::CCDecoder::parseDTVCCPacket(int64_t timeUs, const uint8_t *data, size_t trackIndex = getTrackIndex(kTrackTypeCEA708, service_number, &trackAdded); if (mSelectedTrack == (ssize_t)trackIndex) { sp ccPacket = new ABuffer(block_size); + if (ccPacket->capacity() == 0) { + ALOGW("b/129068792, no memory available, %zu", block_size); + android_errorWriteLog(0x534e4554, "129068792"); + return false; + } memcpy(ccPacket->data(), br.data(), block_size); mCCMap.add(timeUs, ccPacket); } diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 687b5a65f5..c77d082cfe 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -3102,9 +3102,13 @@ sp AudioFlinger::createEffect( } // look for the thread where the specified audio session is present for (size_t i = 0; i < mPlaybackThreads.size(); i++) { - if (mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId) != 0) { + uint32_t sessionType = mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId); + if (sessionType != 0) { io = mPlaybackThreads.keyAt(i); - break; + // thread with same effect session is preferable + if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) { + break; + } } } if (io == AUDIO_IO_HANDLE_NONE) { @@ -3130,6 +3134,21 @@ sp AudioFlinger::createEffect( io = mPlaybackThreads.keyAt(0); } ALOGV("createEffect() got io %d for effect %s", io, desc.name); + } else if (checkPlaybackThread_l(io) != nullptr) { + // allow only one effect chain per sessionId on mPlaybackThreads. + for (size_t i = 0; i < mPlaybackThreads.size(); i++) { + const audio_io_handle_t checkIo = mPlaybackThreads.keyAt(i); + if (io == checkIo) continue; + const uint32_t sessionType = + mPlaybackThreads.valueAt(i)->hasAudioSession(sessionId); + if ((sessionType & ThreadBase::EFFECT_SESSION) != 0) { + ALOGE("%s: effect %s io %d denied because session %d effect exists on io %d", + __func__, desc.name, (int)io, (int)sessionId, (int)checkIo); + android_errorWriteLog(0x534e4554, "123237974"); + lStatus = BAD_VALUE; + goto Exit; + } + } } ThreadBase *thread = checkRecordThread_l(io); if (thread == NULL) {