diff options
author | Jessica Wagantall <jwagantall@cyngn.com> | 2016-07-07 12:07:33 -0700 |
---|---|---|
committer | Jessica Wagantall <jwagantall@cyngn.com> | 2016-07-07 14:15:22 -0700 |
commit | 1e7c9d2c408b17fa14f897cfe8d1ae06fe944637 (patch) | |
tree | 2e132ad77cb30013947b94eeb8d4835bbd01f664 | |
parent | fbef511c958b5f1b3e015d032dcac4ed7cc84876 (diff) | |
parent | d112f7d0c1dbaf0368365885becb11ca8d3f13a4 (diff) | |
download | frameworks_av-1e7c9d2c408b17fa14f897cfe8d1ae06fe944637.zip frameworks_av-1e7c9d2c408b17fa14f897cfe8d1ae06fe944637.tar.gz frameworks_av-1e7c9d2c408b17fa14f897cfe8d1ae06fe944637.tar.bz2 |
Merge remote-tracking branch 'remotes/android-6.0.1_r52' into HEAD
Ticket: CYNGNOS-3020
Change-Id: I7e8d69c5f7041b66893ea643c4bc19c3b7bcdda5
-rw-r--r-- | media/libmedia/Android.mk | 1 | ||||
-rw-r--r-- | media/libmedia/MediaUtils.cpp | 74 | ||||
-rw-r--r-- | media/libmedia/MediaUtils.h | 35 | ||||
-rw-r--r-- | media/libmediaplayerservice/MetadataRetrieverClient.cpp | 1 | ||||
-rw-r--r-- | media/libmediaplayerservice/nuplayer/GenericSource.cpp | 34 | ||||
-rw-r--r-- | media/libstagefright/DRMExtractor.cpp | 12 | ||||
-rwxr-xr-x | media/libstagefright/MPEG4Extractor.cpp | 27 | ||||
-rw-r--r-- | media/libstagefright/SampleIterator.cpp | 5 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c | 24 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ATSParser.cpp | 7 | ||||
-rw-r--r-- | media/mediaserver/Android.mk | 1 | ||||
-rw-r--r-- | media/mediaserver/main_mediaserver.cpp | 6 |
12 files changed, 208 insertions, 19 deletions
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index 74e4eb1..efcd541 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -44,6 +44,7 @@ LOCAL_SRC_FILES:= \ IResourceManagerService.cpp \ IStreamSource.cpp \ MediaCodecInfo.cpp \ + MediaUtils.cpp \ Metadata.cpp \ mediarecorder.cpp \ IMediaMetadataRetriever.cpp \ diff --git a/media/libmedia/MediaUtils.cpp b/media/libmedia/MediaUtils.cpp new file mode 100644 index 0000000..a02ca65 --- /dev/null +++ b/media/libmedia/MediaUtils.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "MediaUtils" +#define LOG_NDEBUG 0 +#include <utils/Log.h> + +#include <cutils/properties.h> +#include <sys/resource.h> +#include <unistd.h> + +#include "MediaUtils.h" + +namespace android { + +void limitProcessMemory( + const char *property, + size_t numberOfBytes, + size_t percentageOfTotalMem) { + + long pageSize = sysconf(_SC_PAGESIZE); + long numPages = sysconf(_SC_PHYS_PAGES); + size_t maxMem = SIZE_MAX; + + if (pageSize > 0 && numPages > 0) { + if (size_t(numPages) < SIZE_MAX / size_t(pageSize)) { + maxMem = size_t(numPages) * size_t(pageSize); + } + ALOGV("physMem: %zu", maxMem); + if (percentageOfTotalMem > 100) { + ALOGW("requested %zu%% of total memory, using 100%%", percentageOfTotalMem); + percentageOfTotalMem = 100; + } + maxMem = maxMem / 100 * percentageOfTotalMem; + if (numberOfBytes < maxMem) { + maxMem = numberOfBytes; + } + ALOGV("requested limit: %zu", maxMem); + } else { + ALOGW("couldn't determine total RAM"); + } + + int64_t propVal = property_get_int64(property, maxMem); + if (propVal > 0 && uint64_t(propVal) <= SIZE_MAX) { + maxMem = propVal; + } + ALOGV("actual limit: %zu", maxMem); + + struct rlimit limit; + getrlimit(RLIMIT_AS, &limit); + ALOGV("original limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max); + limit.rlim_cur = maxMem; + setrlimit(RLIMIT_AS, &limit); + limit.rlim_cur = -1; + limit.rlim_max = -1; + getrlimit(RLIMIT_AS, &limit); + ALOGV("new limits: %lld/%lld", (long long)limit.rlim_cur, (long long)limit.rlim_max); + +} + +} // namespace android diff --git a/media/libmedia/MediaUtils.h b/media/libmedia/MediaUtils.h new file mode 100644 index 0000000..f80dd30 --- /dev/null +++ b/media/libmedia/MediaUtils.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _MEDIA_UTILS_H +#define _MEDIA_UTILS_H + +namespace android { + +/** + Limit the amount of memory a process can allocate using setrlimit(RLIMIT_AS). + The value to use will be read from the specified system property, or if the + property doesn't exist it will use the specified number of bytes or the + specified percentage of total memory, whichever is smaller. +*/ +void limitProcessMemory( + const char *property, + size_t numberOfBytes, + size_t percentageOfTotalMem); + +} // namespace android + +#endif // _MEDIA_UTILS_H diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp index 7bd99cc..f725b90 100644 --- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp +++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp @@ -228,6 +228,7 @@ sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option) ALOGV("rotation: %d", frameCopy->mRotationAngle); frameCopy->mData = (uint8_t *)frameCopy + sizeof(VideoFrame); memcpy(frameCopy->mData, frame->mData, frame->mSize); + frameCopy->mData = 0; delete frame; // Fix memory leakage return mThumbnail; } diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp index beda8bd..949c12f 100644 --- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp +++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp @@ -232,6 +232,9 @@ status_t NuPlayer::GenericSource::initFromDataSource() { for (size_t i = 0; i < numtracks; ++i) { sp<MediaSource> track = extractor->getTrack(i); + if (track == NULL) { + continue; + } sp<MetaData> meta = extractor->getTrackMetaData(i); @@ -274,24 +277,27 @@ status_t NuPlayer::GenericSource::initFromDataSource() { } } - if (track != NULL) { - mSources.push(track); - int64_t durationUs; - if (meta->findInt64(kKeyDuration, &durationUs)) { - if (durationUs > mDurationUs) { - mDurationUs = durationUs; - } + 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; - } + int32_t bitrate; + if (totalBitrate >= 0 && meta->findInt32(kKeyBitRate, &bitrate)) { + totalBitrate += bitrate; + } else { + totalBitrate = -1; } } + if (mSources.size() == 0) { + ALOGE("b/23705695"); + return UNKNOWN_ERROR; + } + mBitrate = totalBitrate; return OK; @@ -339,7 +345,7 @@ int64_t NuPlayer::GenericSource::getLastReadPosition() { status_t NuPlayer::GenericSource::setBuffers( bool audio, Vector<MediaBuffer *> &buffers) { - if ((mIsSecure || mUseSetBuffers) && !audio) { + if (mIsSecure && !audio && mVideoTrack.mSource != NULL) { return mVideoTrack.mSource->setBuffers(buffers); } return INVALID_OPERATION; diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp index 9cb6e86..e2bc89c 100644 --- a/media/libstagefright/DRMExtractor.cpp +++ b/media/libstagefright/DRMExtractor.cpp @@ -200,7 +200,17 @@ status_t DRMSource::read(MediaBuffer **buffer, const ReadOptions *options) { continue; } - CHECK(dstOffset + 4 <= (*buffer)->size()); + if (dstOffset > SIZE_MAX - 4 || + dstOffset + 4 > SIZE_MAX - nalLength || + dstOffset + 4 + nalLength > (*buffer)->size()) { + (*buffer)->release(); + (*buffer) = NULL; + if (decryptedDrmBuffer.data) { + delete [] decryptedDrmBuffer.data; + decryptedDrmBuffer.data = NULL; + } + return ERROR_MALFORMED; + } dstData[dstOffset++] = 0; dstData[dstOffset++] = 0; diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index f606366..89b561e 100755 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -544,7 +544,10 @@ status_t MPEG4Extractor::readMetaData() { } if (psshsize > 0 && psshsize <= UINT32_MAX) { char *buf = (char*)malloc(psshsize); - CHECK(buf != NULL); + if (!buf) { + ALOGE("b/28471206"); + return NO_MEMORY; + } char *ptr = buf; for (size_t i = 0; i < mPssh.size(); i++) { memcpy(ptr, mPssh[i].uuid, 20); // uuid + length @@ -939,6 +942,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { } if (isTrack) { + int32_t trackId; + // There must be exact one track header per track. + if (!mLastTrack->meta->findInt32(kKeyTrackID, &trackId)) { + mLastTrack->skipTrack = true; + } if (mLastTrack->skipTrack) { Track *cur = mFirstTrack; @@ -1730,6 +1738,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { sp<ABuffer> buffer = new ABuffer(chunk_data_size); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } + if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { return ERROR_IO; @@ -1747,6 +1760,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { { sp<ABuffer> buffer = new ABuffer(chunk_data_size); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } + if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) < chunk_data_size) { return ERROR_IO; @@ -2082,6 +2100,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) { return ERROR_MALFORMED; } sp<ABuffer> buffer = new ABuffer(chunk_data_size + 1); + if (buffer->data() == NULL) { + ALOGE("b/28471206"); + return NO_MEMORY; + } if (mDataSource->readAt( data_offset, buffer->data(), chunk_data_size) != (ssize_t)chunk_data_size) { return ERROR_IO; @@ -2882,6 +2904,9 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) { break; } } + } else { + ALOGE("b/21657957"); + return NULL; } ALOGV("getTrack called, pssh: %zu", mPssh.size()); diff --git a/media/libstagefright/SampleIterator.cpp b/media/libstagefright/SampleIterator.cpp index 6042a9a..0efa270 100644 --- a/media/libstagefright/SampleIterator.cpp +++ b/media/libstagefright/SampleIterator.cpp @@ -95,6 +95,11 @@ status_t SampleIterator::seekTo(uint32_t sampleIndex) { CHECK(sampleIndex < mStopChunkSampleIndex); + if (mSamplesPerChunk == 0) { + ALOGE("b/22802344"); + return ERROR_MALFORMED; + } + uint32_t chunk = (sampleIndex - mFirstChunkSampleIndex) / mSamplesPerChunk + mFirstChunk; diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c index 3234754..ff7a42a 100644 --- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c +++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_storage.c @@ -58,6 +58,10 @@ 3. Module defines ------------------------------------------------------------------------------*/ +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + /*------------------------------------------------------------------------------ 4. Local function prototypes ------------------------------------------------------------------------------*/ @@ -326,9 +330,23 @@ u32 h264bsdActivateParamSets(storage_t *pStorage, u32 ppsId, u32 isIdr) pStorage->activePps = pStorage->pps[ppsId]; pStorage->activeSpsId = pStorage->activePps->seqParameterSetId; pStorage->activeSps = pStorage->sps[pStorage->activeSpsId]; - pStorage->picSizeInMbs = - pStorage->activeSps->picWidthInMbs * - pStorage->activeSps->picHeightInMbs; + + /* report error before multiplication to prevent integer overflow */ + if (pStorage->activeSps->picWidthInMbs == 0) + { + pStorage->picSizeInMbs = 0; + } + else if (pStorage->activeSps->picHeightInMbs > + UINT32_MAX / pStorage->activeSps->picWidthInMbs) + { + return(MEMORY_ALLOCATION_ERROR); + } + else + { + pStorage->picSizeInMbs = + pStorage->activeSps->picWidthInMbs * + pStorage->activeSps->picHeightInMbs; + } pStorage->currImage->width = pStorage->activeSps->picWidthInMbs; pStorage->currImage->height = pStorage->activeSps->picHeightInMbs; diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp index f9a9c4c..3ad3118 100644 --- a/media/libstagefright/mpeg2ts/ATSParser.cpp +++ b/media/libstagefright/mpeg2ts/ATSParser.cpp @@ -1713,6 +1713,13 @@ bool ATSParser::PSISection::isCRCOkay() const { unsigned sectionLength = U16_AT(data + 1) & 0xfff; ALOGV("sectionLength %u, skip %u", sectionLength, mSkipBytes); + + if(sectionLength < mSkipBytes) { + ALOGE("b/28333006"); + android_errorWriteLog(0x534e4554, "28333006"); + return false; + } + // Skip the preceding field present when payload start indicator is on. sectionLength -= mSkipBytes; diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk index 33766b5..ac25582 100644 --- a/media/mediaserver/Android.mk +++ b/media/mediaserver/Android.mk @@ -37,6 +37,7 @@ LOCAL_STATIC_LIBRARIES := \ LOCAL_C_INCLUDES := \ frameworks/av/media/libmediaplayerservice \ + frameworks/av/media/libmedia \ frameworks/av/services/medialog \ frameworks/av/services/audioflinger \ frameworks/av/services/audiopolicy \ diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp index c16e646..f785c0d 100644 --- a/media/mediaserver/main_mediaserver.cpp +++ b/media/mediaserver/main_mediaserver.cpp @@ -36,6 +36,7 @@ #include "MediaPlayerService.h" #include "ResourceManagerService.h" #include "service/AudioPolicyService.h" +#include "MediaUtils.h" #include "SoundTriggerHwService.h" #include "RadioService.h" @@ -47,6 +48,11 @@ using namespace android; int main(int argc __unused, char** argv) { + limitProcessMemory( + "ro.media.maxmem", /* property that defines limit */ + SIZE_MAX, /* upper limit in bytes */ + 65 /* upper limit as percentage of physical RAM */); + signal(SIGPIPE, SIG_IGN); char value[PROPERTY_VALUE_MAX]; bool doLog = (property_get("ro.test_harness", value, "0") > 0) && (atoi(value) == 1); |