summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorWonsik Kim <wonsik@google.com>2016-03-20 10:44:44 +0900
committerThe Android Automerger <android-build@google.com>2016-04-21 19:09:55 -0700
commitd2f47191538837e796e2b10c1ff7e1ee35f6e0ab (patch)
treeaf1b0470da255756c44fa2b1c790ee2bbd84bf4d /media
parent4e32001e4196f39ddd0b86686ae0231c8f5ed944 (diff)
downloadframeworks_av-d2f47191538837e796e2b10c1ff7e1ee35f6e0ab.zip
frameworks_av-d2f47191538837e796e2b10c1ff7e1ee35f6e0ab.tar.gz
frameworks_av-d2f47191538837e796e2b10c1ff7e1ee35f6e0ab.tar.bz2
codecs: check OMX buffer size before use in (h263|h264)dec
Bug: 27833616 Change-Id: I0fd599b3da431425d89236ffdd9df423c11947c0
Diffstat (limited to 'media')
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp10
-rw-r--r--media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp26
-rw-r--r--media/libstagefright/codecs/on2/h264dec/SoftAVC.h2
3 files changed, 31 insertions, 7 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index 0c1a149..bb59ae4 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -229,6 +229,14 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
int32_t bufferSize = inHeader->nFilledLen;
int32_t tmp = bufferSize;
+ OMX_U32 frameSize = (mWidth * mHeight * 3) / 2;
+ if (outHeader->nAllocLen < frameSize) {
+ android_errorWriteLog(0x534e4554, "27833616");
+ ALOGE("Insufficient output buffer size");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
// The PV decoder is lying to us, sometimes it'll claim to only have
// consumed a subset of the buffer when it clearly consumed all of it.
// ignore whatever it says...
@@ -272,7 +280,7 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
++mInputBufferCount;
outHeader->nOffset = 0;
- outHeader->nFilledLen = (mWidth * mHeight * 3) / 2;
+ outHeader->nFilledLen = frameSize;
List<BufferInfo *>::iterator it = outQueue.begin();
while ((*it)->mHeader != outHeader) {
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
index 6b8b395..2f61d12 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
@@ -202,7 +202,12 @@ void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) {
}
if (mFirstPicture && !outQueue.empty()) {
- drainOneOutputBuffer(mFirstPictureId, mFirstPicture);
+ if (!drainOneOutputBuffer(mFirstPictureId, mFirstPicture)) {
+ ALOGE("Drain failed");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
delete[] mFirstPicture;
mFirstPicture = NULL;
mFirstPictureId = -1;
@@ -242,15 +247,20 @@ void SoftAVC::saveFirstOutputBuffer(int32_t picId, uint8_t *data) {
memcpy(mFirstPicture, data, pictureSize);
}
-void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
+bool SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex);
BufferInfo *outInfo = *outQueue.begin();
- outQueue.erase(outQueue.begin());
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ OMX_U32 frameSize = mWidth * mHeight * 3 / 2;
+ if (outHeader->nAllocLen - outHeader->nOffset < frameSize) {
+ android_errorWriteLog(0x534e4554, "27833616");
+ return false;
+ }
+ outQueue.erase(outQueue.begin());
OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId);
outHeader->nTimeStamp = header->nTimeStamp;
outHeader->nFlags = header->nFlags;
- outHeader->nFilledLen = mWidth * mHeight * 3 / 2;
+ outHeader->nFilledLen = frameSize;
uint8_t *dst = outHeader->pBuffer + outHeader->nOffset;
const uint8_t *srcY = data;
@@ -265,6 +275,7 @@ void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) {
delete header;
outInfo->mOwnedByUs = false;
notifyFillBufferDone(outHeader);
+ return true;
}
void SoftAVC::drainAllOutputBuffers(bool eos) {
@@ -277,7 +288,12 @@ void SoftAVC::drainAllOutputBuffers(bool eos) {
mHandle, &decodedPicture, eos /* flush */)) {
int32_t picId = decodedPicture.picId;
uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture;
- drainOneOutputBuffer(picId, data);
+ if (!drainOneOutputBuffer(picId, data)) {
+ ALOGE("Drain failed");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
}
}
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
index 069107d..b8c1807 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h
@@ -71,7 +71,7 @@ private:
status_t initDecoder();
void drainAllOutputBuffers(bool eos);
- void drainOneOutputBuffer(int32_t picId, uint8_t *data);
+ bool drainOneOutputBuffer(int32_t picId, uint8_t *data);
void saveFirstOutputBuffer(int32_t pidId, uint8_t *data);
CropSettingsMode handleCropParams(const H264SwDecInfo& decInfo);