Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d46c937 authored by Jon Larimer's avatar Jon Larimer Committed by Android (Google) Code Review
Browse files

Merge "MPEG4Source::fragmentedRead: check range before writing into buffers" into klp-dev

parents aa1cc741 f810a829
Loading
Loading
Loading
Loading
+40 −8
Original line number Diff line number Diff line
@@ -3475,6 +3475,14 @@ status_t MPEG4Source::fragmentedRead(

    if (!mIsAVC || mWantsNALFragments) {
        if (newBuffer) {
            if (!isInRange((size_t)0u, mBuffer->size(), size)) {
                mBuffer->release();
                mBuffer = NULL;

                ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
                return ERROR_MALFORMED;
            }

            ssize_t num_bytes_read =
                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);

@@ -3482,7 +3490,7 @@ status_t MPEG4Source::fragmentedRead(
                mBuffer->release();
                mBuffer = NULL;

                ALOGV("i/o error");
                ALOGE("i/o error");
                return ERROR_IO;
            }

@@ -3552,18 +3560,40 @@ status_t MPEG4Source::fragmentedRead(
        ssize_t num_bytes_read = 0;
        int32_t drm = 0;
        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
        void *data = NULL;
        bool isMalFormed = false;
        if (usesDRM) {
            num_bytes_read =
                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
                isMalFormed = true;
            } else {
            num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
                data = mBuffer->data();
            }
        } else {
            int32_t max_size;
            if (mFormat == NULL
                    || !mFormat->findInt32(kKeyMaxInputSize, &max_size)
                    || !isInRange((size_t)0u, (size_t)max_size, size)) {
                isMalFormed = true;
            } else {
                data = mSrcBuffer;
            }
        }

        if (isMalFormed || data == NULL) {
            ALOGE("isMalFormed size %zu", size);
            if (mBuffer != NULL) {
                mBuffer->release();
                mBuffer = NULL;
            }
            return ERROR_MALFORMED;
        }
        num_bytes_read = mDataSource->readAt(offset, data, size);

        if (num_bytes_read < (ssize_t)size) {
            mBuffer->release();
            mBuffer = NULL;

            ALOGV("i/o error");
            ALOGE("i/o error");
            return ERROR_IO;
        }

@@ -3577,16 +3607,18 @@ status_t MPEG4Source::fragmentedRead(
            size_t dstOffset = 0;

            while (srcOffset < size) {
                bool isMalFormed = !isInRange(0u, size, srcOffset, mNALLengthSize);
                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
                size_t nalLength = 0;
                if (!isMalFormed) {
                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
                    srcOffset += mNALLengthSize;
                    isMalFormed = !isInRange(0u, size, srcOffset, nalLength);
                    isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
                            || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
                }

                if (isMalFormed) {
                    ALOGE("Video is malformed");
                    ALOGE("Video is malformed; nalLength %zu", nalLength);
                    mBuffer->release();
                    mBuffer = NULL;
                    return ERROR_MALFORMED;