Merge "stagefright: MPEG4Extractor: allow 'hdlr' box before first track" into klp-dev
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 6643736..d7be06f 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -203,6 +203,12 @@
     virtual status_t onTransact(
             uint32_t code, const Parcel &data, Parcel *reply,
             uint32_t flags = 0);
+
+protected:
+    // check if the codec is secure.
+    virtual bool isSecure(IOMX::node_id node) {
+        return false;
+    }
 };
 
 class BnOMXObserver : public BnInterface<IOMXObserver> {
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 71ce320..10747f3 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -810,6 +810,12 @@
 
             node_id node = (void*)data.readIntPtr();
             OMX_U32 port_index = data.readInt32();
+            if (!isSecure(node) || port_index != 0 /* kPortIndexInput */) {
+                ALOGE("b/24310423");
+                reply->writeInt32(INVALID_OPERATION);
+                return NO_ERROR;
+            }
+
             size_t size = data.readInt32();
 
             buffer_id buffer;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index ca3e92f..f0988eb 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -2155,6 +2155,12 @@
                     mLastCommentName.setTo((const char *)buffer + 4);
                     break;
                 case FOURCC('d', 'a', 't', 'a'):
+                    if (size < 8) {
+                        delete[] buffer;
+                        buffer = NULL;
+                        ALOGE("b/24346430");
+                        return ERROR_MALFORMED;
+                    }
                     mLastCommentData.setTo((const char *)buffer + 8);
                     break;
             }
@@ -3295,7 +3301,10 @@
             (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
 
         size_t nal_size = parseNALSize(src);
-        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
+        if (mNALLengthSize > SIZE_MAX - nal_size) {
+            ALOGE("b/24441553, b/24445122");
+        }
+        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
             ALOGE("incomplete NAL unit.");
 
             mBuffer->release();
@@ -3568,7 +3577,11 @@
             (const uint8_t *)mBuffer->data() + mBuffer->range_offset();
 
         size_t nal_size = parseNALSize(src);
-        if (mBuffer->range_length() < mNALLengthSize + nal_size) {
+        if (mNALLengthSize > SIZE_MAX - nal_size) {
+            ALOGE("b/24441553, b/24445122");
+        }
+
+        if (mBuffer->range_length() - mNALLengthSize < nal_size) {
             ALOGE("incomplete NAL unit.");
 
             mBuffer->release();
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
index e9ead01..03e4119 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/conceal.cpp
@@ -19,6 +19,7 @@
 #include "vlc_decode.h"
 #include "bitstream.h"
 #include "scaling.h"
+#include "log/log.h"
 
 /* ====================================================================== /
 Function : ConcealTexture_I()
@@ -137,6 +138,10 @@
 ****************************************************************************/
 void CopyVopMB(Vop *curr, uint8 *prevFrame, int mbnum, int width_Y, int height)
 {
+    if (curr == NULL || prevFrame == NULL) {
+        ALOGE("b/24630158");
+        return;
+    }
     int width_C = width_Y >> 1;
     int row = MB_SIZE;
     uint8              *y1, *y2, *u1, *u2, *v1, *v2;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 5a490e9..3592fee 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -194,6 +194,13 @@
 
     if (header.version_major == 4) {
         void *copy = malloc(size);
+        if (copy == NULL) {
+            free(mData);
+            mData = NULL;
+            ALOGE("b/24623447, no more memory");
+            return false;
+        }
+
         memcpy(copy, mData, size);
 
         bool success = removeUnsynchronizationV2_4(false /* iTunesHack */);
@@ -234,7 +241,14 @@
             return false;
         }
 
-        size_t extendedHeaderSize = U32_AT(&mData[0]) + 4;
+        size_t extendedHeaderSize = U32_AT(&mData[0]);
+        if (extendedHeaderSize > SIZE_MAX - 4) {
+            free(mData);
+            mData = NULL;
+            ALOGE("b/24623447, extendedHeaderSize is too large");
+            return false;
+        }
+        extendedHeaderSize += 4;
 
         if (extendedHeaderSize > mSize) {
             free(mData);
@@ -252,7 +266,10 @@
             if (extendedHeaderSize >= 10) {
                 size_t paddingSize = U32_AT(&mData[6]);
 
-                if (mFirstFrameOffset + paddingSize > mSize) {
+                if (paddingSize > SIZE_MAX - mFirstFrameOffset) {
+                    ALOGE("b/24623447, paddingSize is too large");
+                }
+                if (paddingSize > mSize - mFirstFrameOffset) {
                     free(mData);
                     mData = NULL;
 
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 31a5077..2bc3759 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -126,6 +126,8 @@
 
     virtual void binderDied(const wp<IBinder> &the_late_who);
 
+    virtual bool isSecure(IOMX::node_id node);
+
     OMX_ERRORTYPE OnEvent(
             node_id node,
             OMX_IN OMX_EVENTTYPE eEvent,
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 339179e..30d9584 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -31,7 +31,7 @@
 
 struct OMXNodeInstance {
     OMXNodeInstance(
-            OMX *owner, const sp<IOMXObserver> &observer);
+            OMX *owner, const sp<IOMXObserver> &observer, const char *name);
 
     void setHandle(OMX::node_id node_id, OMX_HANDLETYPE handle);
 
@@ -110,6 +110,10 @@
             const void *data,
             size_t size);
 
+    bool isSecure() const {
+        return mIsSecure;
+    }
+
     void onMessage(const omx_message &msg);
     void onObserverDied(OMXMaster *master);
     void onGetHandleFailed();
@@ -125,6 +129,7 @@
     OMX_HANDLETYPE mHandle;
     sp<IOMXObserver> mObserver;
     bool mDying;
+    bool mIsSecure;
 
     // Lock only covers mGraphicBufferSource.  We can't always use mLock
     // because of rare instances where we'd end up locking it recursively.
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 84a0e10..415910a 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -185,6 +185,11 @@
     instance->onObserverDied(mMaster);
 }
 
+bool OMX::isSecure(node_id node) {
+    OMXNodeInstance *instance = findInstance(node);
+    return (instance == NULL ? false : instance->isSecure());
+}
+
 bool OMX::livesLocally(node_id node, pid_t pid) {
     return pid == getpid();
 }
@@ -223,7 +228,7 @@
 
     *node = 0;
 
-    OMXNodeInstance *instance = new OMXNodeInstance(this, observer);
+    OMXNodeInstance *instance = new OMXNodeInstance(this, observer, name);
 
     OMX_COMPONENTTYPE *handle;
     OMX_ERRORTYPE err = mMaster->makeComponentInstance(
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 4fe41c9..577e804 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -90,12 +90,13 @@
 };
 
 OMXNodeInstance::OMXNodeInstance(
-        OMX *owner, const sp<IOMXObserver> &observer)
+        OMX *owner, const sp<IOMXObserver> &observer, const char *name)
     : mOwner(owner),
       mNodeID(NULL),
       mHandle(NULL),
       mObserver(observer),
       mDying(false) {
+    mIsSecure = AString(name).endsWith(".secure");
 }
 
 OMXNodeInstance::~OMXNodeInstance() {
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a9eaa8a..994c7db 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5223,6 +5223,7 @@
     mBufferSize = mInput->stream->common.get_buffer_size(&mInput->stream->common);
     mFrameCount = mBufferSize / mFrameSize;
     mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
+    memset(mRsmpInBuffer, 0, mFrameCount * mChannelCount * sizeof(mRsmpInBuffer[0]));
 
     if (mSampleRate != mReqSampleRate && mChannelCount <= FCC_2 && mReqChannelCount <= FCC_2)
     {