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

Commit f810a829 authored by Robert Shih's avatar Robert Shih
Browse files

MPEG4Source::fragmentedRead: check range before writing into buffers

Bug: 22008959
Change-Id: I5f6e188adcc593796455bdaf7b0b8aba672b106e
parent 4254be9a
Loading
Loading
Loading
Loading
+40 −8
Original line number Original line Diff line number Diff line
@@ -3446,6 +3446,14 @@ status_t MPEG4Source::fragmentedRead(


    if (!mIsAVC || mWantsNALFragments) {
    if (!mIsAVC || mWantsNALFragments) {
        if (newBuffer) {
        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 =
            ssize_t num_bytes_read =
                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
                mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);


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


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


@@ -3523,18 +3531,40 @@ status_t MPEG4Source::fragmentedRead(
        ssize_t num_bytes_read = 0;
        ssize_t num_bytes_read = 0;
        int32_t drm = 0;
        int32_t drm = 0;
        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
        bool usesDRM = (mFormat->findInt32(kKeyIsDRM, &drm) && drm != 0);
        void *data = NULL;
        bool isMalFormed = false;
        if (usesDRM) {
        if (usesDRM) {
            num_bytes_read =
            if (mBuffer == NULL || !isInRange((size_t)0u, mBuffer->size(), size)) {
                mDataSource->readAt(offset, (uint8_t*)mBuffer->data(), size);
                isMalFormed = true;
            } else {
            } 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) {
        if (num_bytes_read < (ssize_t)size) {
            mBuffer->release();
            mBuffer->release();
            mBuffer = NULL;
            mBuffer = NULL;


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


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


            while (srcOffset < size) {
            while (srcOffset < size) {
                bool isMalFormed = !isInRange(0u, size, srcOffset, mNALLengthSize);
                isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
                size_t nalLength = 0;
                size_t nalLength = 0;
                if (!isMalFormed) {
                if (!isMalFormed) {
                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
                    nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
                    srcOffset += mNALLengthSize;
                    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) {
                if (isMalFormed) {
                    ALOGE("Video is malformed");
                    ALOGE("Video is malformed; nalLength %zu", nalLength);
                    mBuffer->release();
                    mBuffer->release();
                    mBuffer = NULL;
                    mBuffer = NULL;
                    return ERROR_MALFORMED;
                    return ERROR_MALFORMED;