diff options
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp | 21 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h | 1 | ||||
-rwxr-xr-x | media/extractors/mp4/MPEG4Extractor.cpp | 40 | ||||
-rw-r--r-- | media/extractors/mp4/SampleTable.cpp | 17 | ||||
-rw-r--r-- | media/libaaudio/src/binding/IAAudioService.cpp | 73 |
5 files changed, 120 insertions, 32 deletions
diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp index aab475ed88..546eb3eba9 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp @@ -111,6 +111,8 @@ void DrmPlugin::initProperties() { // The content in this secure stop is implementation dependent, the clearkey // secureStop does not serve as a reference implementation. void DrmPlugin::installSecureStop(const hidl_vec<uint8_t>& sessionId) { + Mutex::Autolock lock(mSecureStopLock); + ClearkeySecureStop clearkeySecureStop; clearkeySecureStop.id = uint32ToVector(++mNextSecureStopId); clearkeySecureStop.data.assign(sessionId.begin(), sessionId.end()); @@ -744,6 +746,7 @@ Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId, } Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { + mSecureStopLock.lock(); std::vector<SecureStop> stops; for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) { ClearkeySecureStop clearkeyStop = itr->second; @@ -755,26 +758,32 @@ Return<void> DrmPlugin::getSecureStops(getSecureStops_cb _hidl_cb) { stop.opaqueData = toHidlVec(stopVec); stops.push_back(stop); } + mSecureStopLock.unlock(); + _hidl_cb(Status::OK, stops); return Void(); } Return<void> DrmPlugin::getSecureStop(const hidl_vec<uint8_t>& secureStopId, getSecureStop_cb _hidl_cb) { - SecureStop stop; + std::vector<uint8_t> stopVec; + + mSecureStopLock.lock(); auto itr = mSecureStops.find(toVector(secureStopId)); if (itr != mSecureStops.end()) { ClearkeySecureStop clearkeyStop = itr->second; - std::vector<uint8_t> stopVec; stopVec.insert(stopVec.end(), clearkeyStop.id.begin(), clearkeyStop.id.end()); stopVec.insert(stopVec.end(), clearkeyStop.data.begin(), clearkeyStop.data.end()); + } + mSecureStopLock.unlock(); + SecureStop stop; + if (!stopVec.empty()) { stop.opaqueData = toHidlVec(stopVec); _hidl_cb(Status::OK, stop); } else { _hidl_cb(Status::BAD_VALUE, stop); } - return Void(); } @@ -787,10 +796,12 @@ Return<Status> DrmPlugin::releaseAllSecureStops() { } Return<void> DrmPlugin::getSecureStopIds(getSecureStopIds_cb _hidl_cb) { + mSecureStopLock.lock(); std::vector<SecureStopId> ids; for (auto itr = mSecureStops.begin(); itr != mSecureStops.end(); ++itr) { ids.push_back(itr->first); } + mSecureStopLock.unlock(); _hidl_cb(Status::OK, toHidlVec(ids)); return Void(); @@ -856,6 +867,8 @@ Return<Status> DrmPlugin::releaseSecureStops(const SecureStopRelease& ssRelease) } Return<Status> DrmPlugin::removeSecureStop(const hidl_vec<uint8_t>& secureStopId) { + Mutex::Autolock lock(mSecureStopLock); + if (1 != mSecureStops.erase(toVector(secureStopId))) { return Status::BAD_VALUE; } @@ -863,6 +876,8 @@ Return<Status> DrmPlugin::removeSecureStop(const hidl_vec<uint8_t>& secureStopId } Return<Status> DrmPlugin::removeAllSecureStops() { + Mutex::Autolock lock(mSecureStopLock); + mSecureStops.clear(); mNextSecureStopId = kSecureStopIdStart; return Status::OK; diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h index f294d4d736..3de758945b 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h +++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h @@ -416,6 +416,7 @@ private: } DeviceFiles mFileHandle; + Mutex mSecureStopLock; CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin); }; diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp index 14fe0dc444..fa562f3026 100755 --- a/media/extractors/mp4/MPEG4Extractor.cpp +++ b/media/extractors/mp4/MPEG4Extractor.cpp @@ -4993,8 +4993,11 @@ status_t MPEG4Source::parseChunk(off64_t *offset) { } status_t MPEG4Source::parseSampleAuxiliaryInformationSizes( - off64_t offset, off64_t /* size */) { + off64_t offset, off64_t size) { ALOGV("parseSampleAuxiliaryInformationSizes"); + if (size < 9) { + return -EINVAL; + } // 14496-12 8.7.12 uint8_t version; if (mDataSource->readAt( @@ -5007,25 +5010,32 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationSizes( return ERROR_UNSUPPORTED; } offset++; + size--; uint32_t flags; if (!mDataSource->getUInt24(offset, &flags)) { return ERROR_IO; } offset += 3; + size -= 3; if (flags & 1) { + if (size < 13) { + return -EINVAL; + } uint32_t tmp; if (!mDataSource->getUInt32(offset, &tmp)) { return ERROR_MALFORMED; } mCurrentAuxInfoType = tmp; offset += 4; + size -= 4; if (!mDataSource->getUInt32(offset, &tmp)) { return ERROR_MALFORMED; } mCurrentAuxInfoTypeParameter = tmp; offset += 4; + size -= 4; } uint8_t defsize; @@ -5034,6 +5044,7 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationSizes( } mCurrentDefaultSampleInfoSize = defsize; offset++; + size--; uint32_t smplcnt; if (!mDataSource->getUInt32(offset, &smplcnt)) { @@ -5041,11 +5052,16 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationSizes( } mCurrentSampleInfoCount = smplcnt; offset += 4; - + size -= 4; if (mCurrentDefaultSampleInfoSize != 0) { ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize); return OK; } + if(smplcnt > size) { + ALOGW("b/124525515 - smplcnt(%u) > size(%ld)", (unsigned int)smplcnt, (unsigned long)size); + android_errorWriteLog(0x534e4554, "124525515"); + return -EINVAL; + } if (smplcnt > mCurrentSampleInfoAllocSize) { uint8_t * newPtr = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt); if (newPtr == NULL) { @@ -5061,26 +5077,32 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationSizes( } status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( - off64_t offset, off64_t /* size */) { + off64_t offset, off64_t size) { ALOGV("parseSampleAuxiliaryInformationOffsets"); + if (size < 8) { + return -EINVAL; + } // 14496-12 8.7.13 uint8_t version; if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) { return ERROR_IO; } offset++; + size--; uint32_t flags; if (!mDataSource->getUInt24(offset, &flags)) { return ERROR_IO; } offset += 3; + size -= 3; uint32_t entrycount; if (!mDataSource->getUInt32(offset, &entrycount)) { return ERROR_IO; } offset += 4; + size -= 4; if (entrycount == 0) { return OK; } @@ -5106,19 +5128,31 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets( for (size_t i = 0; i < entrycount; i++) { if (version == 0) { + if (size < 4) { + ALOGW("b/124526959"); + android_errorWriteLog(0x534e4554, "124526959"); + return -EINVAL; + } uint32_t tmp; if (!mDataSource->getUInt32(offset, &tmp)) { return ERROR_IO; } mCurrentSampleInfoOffsets[i] = tmp; offset += 4; + size -= 4; } else { + if (size < 8) { + ALOGW("b/124526959"); + android_errorWriteLog(0x534e4554, "124526959"); + return -EINVAL; + } uint64_t tmp; if (!mDataSource->getUInt64(offset, &tmp)) { return ERROR_IO; } mCurrentSampleInfoOffsets[i] = tmp; offset += 8; + size -= 8; } } diff --git a/media/extractors/mp4/SampleTable.cpp b/media/extractors/mp4/SampleTable.cpp index bf29bf1eac..e7e8901bf1 100644 --- a/media/extractors/mp4/SampleTable.cpp +++ b/media/extractors/mp4/SampleTable.cpp @@ -391,20 +391,11 @@ status_t SampleTable::setTimeToSampleParams( } mTimeToSampleCount = U32_AT(&header[4]); - if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) { - // Choose this bound because - // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one - // time-to-sample entry in the time-to-sample table. - // 2) mTimeToSampleCount is the number of entries of the time-to-sample - // table. - // 3) We hope that the table size does not exceed UINT32_MAX. + if (mTimeToSampleCount > (data_size - 8) / (2 * sizeof(uint32_t))) { ALOGE("Time-to-sample table size too large."); return ERROR_OUT_OF_RANGE; } - // Note: At this point, we know that mTimeToSampleCount * 2 will not - // overflow because of the above condition. - uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t); mTotalSize += allocSize; if (mTotalSize > kMaxTotalSize) { @@ -540,6 +531,12 @@ status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) } uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t); + if (allocSize > data_size - 8) { + ALOGW("b/124771364 - allocSize(%lu) > size(%lu)", + (unsigned long)allocSize, (unsigned long)(data_size - 8)); + android_errorWriteLog(0x534e4554, "124771364"); + return ERROR_MALFORMED; + } if (allocSize > kMaxTotalSize) { ALOGE("Sync sample table size too large."); return ERROR_OUT_OF_RANGE; diff --git a/media/libaaudio/src/binding/IAAudioService.cpp b/media/libaaudio/src/binding/IAAudioService.cpp index 97ad2b02a0..e017b3a122 100644 --- a/media/libaaudio/src/binding/IAAudioService.cpp +++ b/media/libaaudio/src/binding/IAAudioService.cpp @@ -237,12 +237,12 @@ IMPLEMENT_META_INTERFACE(AAudioService, "IAAudioService"); status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { - aaudio_handle_t streamHandle; + aaudio_handle_t streamHandle = 0; aaudio::AAudioStreamRequest request; aaudio::AAudioStreamConfiguration configuration; - pid_t tid; - int64_t nanoseconds; - aaudio_result_t result; + pid_t tid = 0; + int64_t nanoseconds = 0; + aaudio_result_t result = AAUDIO_OK; status_t status = NO_ERROR; ALOGV("BnAAudioService::onTransact(%i) %i", code, flags); @@ -285,7 +285,11 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, case CLOSE_STREAM: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(CLOSE_STREAM) streamHandle failed!", __func__); + return status; + } result = closeStream(streamHandle); //ALOGD("BnAAudioService::onTransact CLOSE_STREAM 0x%08X, result = %d", // streamHandle, result); @@ -297,6 +301,7 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, CHECK_INTERFACE(IAAudioService, data, reply); status = data.readInt32(&streamHandle); if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(GET_STREAM_DESCRIPTION) streamHandle failed!", __func__); return status; } aaudio::AudioEndpointParcelable parcelable; @@ -313,7 +318,11 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, case START_STREAM: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(START_STREAM) streamHandle failed!", __func__); + return status; + } result = startStream(streamHandle); ALOGV("BnAAudioService::onTransact START_STREAM 0x%08X, result = %d", streamHandle, result); @@ -323,7 +332,11 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, case PAUSE_STREAM: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(PAUSE_STREAM) streamHandle failed!", __func__); + return status; + } result = pauseStream(streamHandle); ALOGV("BnAAudioService::onTransact PAUSE_STREAM 0x%08X, result = %d", streamHandle, result); @@ -333,7 +346,11 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, case STOP_STREAM: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(STOP_STREAM) streamHandle failed!", __func__); + return status; + } result = stopStream(streamHandle); ALOGV("BnAAudioService::onTransact STOP_STREAM 0x%08X, result = %d", streamHandle, result); @@ -343,7 +360,11 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, case FLUSH_STREAM: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(FLUSH_STREAM) streamHandle failed!", __func__); + return status; + } result = flushStream(streamHandle); ALOGV("BnAAudioService::onTransact FLUSH_STREAM 0x%08X, result = %d", streamHandle, result); @@ -353,20 +374,40 @@ status_t BnAAudioService::onTransact(uint32_t code, const Parcel& data, case REGISTER_AUDIO_THREAD: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); - data.readInt32(&tid); - data.readInt64(&nanoseconds); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) streamHandle failed!", __func__); + return status; + } + status = data.readInt32(&tid); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) tid failed!", __func__); + return status; + } + status = data.readInt64(&nanoseconds); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(REGISTER_AUDIO_THREAD) nanoseconds failed!", __func__); + return status; + } result = registerAudioThread(streamHandle, tid, nanoseconds); - ALOGV("BnAAudioService::onTransact REGISTER_AUDIO_THREAD 0x%08X, result = %d", - streamHandle, result); + ALOGV("BnAAudioService::%s(REGISTER_AUDIO_THREAD) 0x%08X, result = %d", + __func__, streamHandle, result); reply->writeInt32(result); return NO_ERROR; } break; case UNREGISTER_AUDIO_THREAD: { CHECK_INTERFACE(IAAudioService, data, reply); - data.readInt32(&streamHandle); - data.readInt32(&tid); + status = data.readInt32(&streamHandle); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) streamHandle failed!", __func__); + return status; + } + status = data.readInt32(&tid); + if (status != NO_ERROR) { + ALOGE("BnAAudioService::%s(UNREGISTER_AUDIO_THREAD) tid failed!", __func__); + return status; + } result = unregisterAudioThread(streamHandle, tid); ALOGV("BnAAudioService::onTransact UNREGISTER_AUDIO_THREAD 0x%08X, result = %d", streamHandle, result); |