summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MPEG4Extractor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/MPEG4Extractor.cpp')
-rwxr-xr-xmedia/libstagefright/MPEG4Extractor.cpp55
1 files changed, 52 insertions, 3 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index c7c238e..80ef7b7 100755
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -50,6 +50,12 @@
namespace android {
+enum {
+ // maximum size of an atom. Some atoms can be bigger according to the spec,
+ // but we only allow up to this size.
+ kMaxAtomSize = 64 * 1024 * 1024,
+};
+
class MPEG4Source : public MediaSource {
public:
// Caller retains ownership of both "dataSource" and "sampleTable".
@@ -544,7 +550,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
@@ -842,6 +851,13 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
PathAdder autoAdder(&mPath, chunk_type);
off64_t chunk_data_size = *offset + chunk_size - data_offset;
+ if (chunk_type != FOURCC('m', 'd', 'a', 't') && chunk_data_size > kMaxAtomSize) {
+ char errMsg[100];
+ sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
+ ALOGE("%s (b/28615448)", errMsg);
+ android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg));
+ return ERROR_MALFORMED;
+ }
if (chunk_type != FOURCC('c', 'p', 'r', 't')
&& chunk_type != FOURCC('c', 'o', 'v', 'r')
@@ -939,6 +955,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;
@@ -1032,7 +1053,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
int64_t delay = (media_time * samplerate + 500000) / 1000000;
mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
- int64_t paddingus = duration - (segment_duration + media_time);
+ int64_t paddingus = duration - (int64_t)(segment_duration + media_time);
if (paddingus < 0) {
// track duration from media header (which is what kKeyDuration is) might
// be slightly shorter than the segment duration, which would make the
@@ -1730,6 +1751,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 +1773,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;
@@ -1980,6 +2011,9 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
return ERROR_IO;
}
+ if (mLastTrack == NULL)
+ return ERROR_MALFORMED;
+
uint32_t type = ntohl(buffer);
// For the 3GPP file format, the handler-type within the 'hdlr' box
// shall be 'text'. We also want to support 'sbtl' handler type
@@ -2079,6 +2113,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;
@@ -2879,6 +2917,9 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
break;
}
}
+ } else {
+ ALOGE("b/21657957");
+ return NULL;
}
ALOGV("getTrack called, pssh: %zu", mPssh.size());
@@ -4258,7 +4299,15 @@ status_t MPEG4Source::read(
continue;
}
- CHECK(dstOffset + 4 <= mBuffer->size());
+ if (dstOffset > SIZE_MAX - 4 ||
+ dstOffset + 4 > SIZE_MAX - nalLength ||
+ dstOffset + 4 + nalLength > mBuffer->size()) {
+ ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
+ android_errorWriteLog(0x534e4554, "27208621");
+ mBuffer->release();
+ mBuffer = NULL;
+ return ERROR_MALFORMED;
+ }
dstData[dstOffset++] = 0;
dstData[dstOffset++] = 0;