Merge "Prevent integer issues in ID3::Iterator::findFrame" into klp-dev
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 98b183a..bff4639 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -247,9 +247,9 @@
subSamples,
sizeof(CryptoPlugin::SubSample) * numSubSamples);
- void *dstPtr;
+ void *secureBufferId, *dstPtr;
if (secure) {
- dstPtr = (void *)data.readIntPtr();
+ secureBufferId = (void *)data.readIntPtr();
} else {
dstPtr = malloc(totalSize);
}
@@ -262,7 +262,7 @@
mode,
srcData,
subSamples, numSubSamples,
- dstPtr,
+ secure ? secureBufferId : dstPtr,
&errorDetailMsg);
reply->writeInt32(result);
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 0899362..8ca45ad 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -39,6 +39,10 @@
#include <media/stagefright/MetaData.h>
#include <utils/String8.h>
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
namespace android {
class MPEG4Source : public MediaSource {
@@ -362,7 +366,7 @@
SINF *sinf = mFirstSINF;
while (sinf) {
SINF *next = sinf->next;
- delete sinf->IPMPData;
+ delete[] sinf->IPMPData;
delete sinf;
sinf = next;
}
@@ -679,7 +683,11 @@
return ERROR_MALFORMED;
}
sinf->len = dataLen - 3;
- sinf->IPMPData = new char[sinf->len];
+ sinf->IPMPData = new (std::nothrow) char[sinf->len];
+ if (sinf->IPMPData == NULL) {
+ return ERROR_MALFORMED;
+ }
+ data_offset += 2;
if (mDataSource->readAt(data_offset + 2, sinf->IPMPData, sinf->len) < sinf->len) {
return ERROR_IO;
@@ -1073,7 +1081,10 @@
return ERROR_MALFORMED;
}
- pssh.data = new uint8_t[pssh.datalen];
+ pssh.data = new (std::nothrow) uint8_t[pssh.datalen];
+ if (pssh.data == NULL) {
+ return ERROR_MALFORMED;
+ }
ALOGV("allocated pssh @ %p", pssh.data);
ssize_t requested = (ssize_t) pssh.datalen;
if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
@@ -1739,8 +1750,7 @@
if ((chunk_size > SIZE_MAX) || (SIZE_MAX - chunk_size <= size)) {
return ERROR_MALFORMED;
}
-
- uint8_t *buffer = new uint8_t[size + chunk_size];
+ uint8_t *buffer = new (std::nothrow) uint8_t[size + chunk_size];
if (buffer == NULL) {
return ERROR_MALFORMED;
}
@@ -2033,7 +2043,10 @@
return ERROR_MALFORMED;
}
- uint8_t *buffer = new uint8_t[size + 1];
+ uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
+ if (buffer == NULL) {
+ return ERROR_MALFORMED;
+ }
if (mDataSource->readAt(
offset, buffer, size) != (ssize_t)size) {
delete[] buffer;
@@ -2498,7 +2511,11 @@
mGroup->add_buffer(new MediaBuffer(max_size));
- mSrcBuffer = new uint8_t[max_size];
+ mSrcBuffer = new (std::nothrow) uint8_t[max_size];
+ if (mSrcBuffer == NULL) {
+ // file probably specified a bad max size
+ return ERROR_MALFORMED;
+ }
mStarted = true;
@@ -2714,13 +2731,27 @@
return ERROR_IO;
}
offset += 4;
+ if (entrycount == 0) {
+ return OK;
+ }
+ if (entrycount > UINT32_MAX / 8) {
+ return ERROR_MALFORMED;
+ }
if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
- mCurrentSampleInfoOffsets = (uint64_t*) realloc(mCurrentSampleInfoOffsets, entrycount * 8);
+ uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
+ if (newPtr == NULL) {
+ return NO_MEMORY;
+ }
+ mCurrentSampleInfoOffsets = newPtr;
mCurrentSampleInfoOffsetsAllocSize = entrycount;
}
mCurrentSampleInfoOffsetCount = entrycount;
+ if (mCurrentSampleInfoOffsets == NULL) {
+ return OK;
+ }
+
for (size_t i = 0; i < entrycount; i++) {
if (version == 0) {
uint32_t tmp;
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 52ce82b..116f358 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -27,6 +27,11 @@
#include <media/stagefright/DataSource.h>
#include <media/stagefright/Utils.h>
+/* TODO: remove after being merged into other branches */
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
namespace android {
// static
@@ -282,6 +287,9 @@
mDefaultSampleSize = U32_AT(&header[4]);
mNumSampleSizes = U32_AT(&header[8]);
+ if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
+ return ERROR_MALFORMED;
+ }
if (type == kSampleSizeType32) {
mSampleSizeFieldSize = 32;
@@ -498,7 +506,7 @@
void SampleTable::buildSampleEntriesTable() {
Mutex::Autolock autoLock(mLock);
- if (mSampleTimeEntries != NULL) {
+ if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
return;
}
@@ -540,6 +548,10 @@
uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
buildSampleEntriesTable();
+ if (mSampleTimeEntries == NULL) {
+ return ERROR_OUT_OF_RANGE;
+ }
+
uint32_t left = 0;
uint32_t right = mNumSampleSizes;
while (left < right) {
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
index 773854f..4d15d7e 100644
--- a/media/libstagefright/SkipCutBuffer.cpp
+++ b/media/libstagefright/SkipCutBuffer.cpp
@@ -25,6 +25,13 @@
namespace android {
SkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut) {
+
+ if (skip < 0 || cut < 0 || cut > 64 * 1024) {
+ ALOGW("out of range skip/cut: %d/%d, using passthrough instead", skip, cut);
+ skip = 0;
+ cut = 0;
+ }
+
mFrontPadding = skip;
mBackPadding = cut;
mWriteHead = 0;
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 216a329..80d8cef 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -68,6 +68,23 @@
return ((uint64_t)htonl(x & 0xffffffff) << 32) | htonl(x >> 32);
}
+static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_t length) {
+ if (((*buffer)->size() + 4 + length) > ((*buffer)->capacity() - (*buffer)->offset())) {
+ sp<ABuffer> tmpBuffer = new (std::nothrow) ABuffer((*buffer)->size() + 4 + length + 1024);
+ if (tmpBuffer.get() == NULL || tmpBuffer->base() == NULL) {
+ return NO_MEMORY;
+ }
+ memcpy(tmpBuffer->data(), (*buffer)->data(), (*buffer)->size());
+ tmpBuffer->setRange(0, (*buffer)->size());
+ (*buffer) = tmpBuffer;
+ }
+
+ memcpy((*buffer)->data() + (*buffer)->size(), "\x00\x00\x00\x01", 4);
+ memcpy((*buffer)->data() + (*buffer)->size() + 4, ptr, length);
+ (*buffer)->setRange((*buffer)->offset(), (*buffer)->size() + 4 + length);
+ return OK;
+}
+
status_t convertMetaDataToMessage(
const sp<MetaData> &meta, sp<AMessage> *format) {
format->clear();
@@ -163,7 +180,10 @@
ptr += 6;
size -= 6;
- sp<ABuffer> buffer = new ABuffer(1024);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(1024);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
buffer->setRange(0, 0);
for (size_t i = 0; i < numSeqParameterSets; ++i) {
@@ -173,11 +193,13 @@
ptr += 2;
size -= 2;
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
+ if (size < length) {
+ return BAD_VALUE;
+ }
+ status_t err = copyNALUToABuffer(&buffer, ptr, length);
+ if (err != OK) {
+ return err;
+ }
ptr += length;
size -= length;
@@ -188,7 +210,10 @@
msg->setBuffer("csd-0", buffer);
- buffer = new ABuffer(1024);
+ buffer = new (std::nothrow) ABuffer(1024);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
buffer->setRange(0, 0);
CHECK(size >= 1);
@@ -203,11 +228,13 @@
ptr += 2;
size -= 2;
- CHECK(size >= length);
-
- memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
- memcpy(buffer->data() + buffer->size() + 4, ptr, length);
- buffer->setRange(0, buffer->size() + 4 + length);
+ if (size < length) {
+ return BAD_VALUE;
+ }
+ status_t err = copyNALUToABuffer(&buffer, ptr, length);
+ if (err != OK) {
+ return err;
+ }
ptr += length;
size -= length;
@@ -225,7 +252,10 @@
esds.getCodecSpecificInfo(
&codec_specific_data, &codec_specific_data_size);
- sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(codec_specific_data_size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), codec_specific_data,
codec_specific_data_size);
@@ -234,7 +264,10 @@
buffer->meta()->setInt64("timeUs", 0);
msg->setBuffer("csd-0", buffer);
} else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
- sp<ABuffer> buffer = new ABuffer(size);
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
@@ -245,7 +278,10 @@
return -EINVAL;
}
- buffer = new ABuffer(size);
+ buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
memcpy(buffer->data(), data, size);
buffer->meta()->setInt32("csd", true);
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index 419e3f4..30d5cbd 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -338,7 +338,7 @@
video->prevVop->uChan = video->prevVop->yChan + size;
video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
#else
- if (size > INT32_MAX / 3 * 2) {
+ if (size > INT32_MAX / 3) {
return PV_FALSE;
}
video->currVop->yChan = (PIXEL *) oscl_malloc(size * 3 / 2); /* Allocate memory for all VOP OKA 3/2/1*/
@@ -368,7 +368,7 @@
{
oscl_memset(video->prevEnhcVop, 0, sizeof(Vop));
#ifndef PV_MEMORY_POOL
- if (size > INT32_MAX / 3 * 2) {
+ if (size > INT32_MAX / 3) {
return PV_FALSE;
}
diff --git a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
index aa8ffc6..851805f 100644
--- a/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4AudioAssembler.cpp
@@ -404,8 +404,9 @@
break;
}
}
-
- CHECK_LE(offset + payloadLength, buffer->size());
+
+ CHECK_LT(offset, buffer->size());
+ CHECK_LE(payloadLength, buffer->size() - offset);
memcpy(out->data() + out->size(), &ptr[offset], payloadLength);
out->setRange(0, out->size() + payloadLength);