From bfed843041b6aaec13ee19996748a7a1476db9c8 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Wed, 1 Apr 2015 19:32:25 -0700 Subject: Add AUtils::isInRange, and use it to detect malformed MPEG4 nal sizes Bug: 19641538 Change-Id: I5aae3f100846c125decc61eec7cd6563e3f33777 --- media/libstagefright/MPEG4Extractor.cpp | 12 ++--- media/libstagefright/tests/Utils_test.cpp | 81 +++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 6 deletions(-) (limited to 'media') diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index d922dc0..080dcd1 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -221,8 +222,7 @@ status_t MPEG4DataSource::initCheck() const { ssize_t MPEG4DataSource::readAt(off64_t offset, void *data, size_t size) { Mutex::Autolock autoLock(mLock); - if (offset >= mCachedOffset - && offset + size <= mCachedOffset + mCachedSize) { + if (isInRange(mCachedOffset, mCachedSize, offset, size)) { memcpy(data, &mCache[offset - mCachedOffset], size); return size; } @@ -3879,12 +3879,12 @@ status_t MPEG4Source::read( size_t dstOffset = 0; while (srcOffset < size) { - bool isMalFormed = (srcOffset + mNALLengthSize > size); + bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); size_t nalLength = 0; if (!isMalFormed) { nalLength = parseNALSize(&mSrcBuffer[srcOffset]); srcOffset += mNALLengthSize; - isMalFormed = srcOffset + nalLength > size; + isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength); } if (isMalFormed) { @@ -4156,12 +4156,12 @@ status_t MPEG4Source::fragmentedRead( size_t dstOffset = 0; while (srcOffset < size) { - bool isMalFormed = (srcOffset + mNALLengthSize > size); + bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize); size_t nalLength = 0; if (!isMalFormed) { nalLength = parseNALSize(&mSrcBuffer[srcOffset]); srcOffset += mNALLengthSize; - isMalFormed = srcOffset + nalLength > size; + isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength); } if (isMalFormed) { diff --git a/media/libstagefright/tests/Utils_test.cpp b/media/libstagefright/tests/Utils_test.cpp index f2825dd..1c13f19 100644 --- a/media/libstagefright/tests/Utils_test.cpp +++ b/media/libstagefright/tests/Utils_test.cpp @@ -90,6 +90,87 @@ TEST_F(UtilsTest, TestMathTemplates) { ASSERT_EQ(max(-4.3, 8.6), 8.6); ASSERT_EQ(max(8.6, -4.3), 8.6); + ASSERT_FALSE(isInRange(-43, 86u, -44)); + ASSERT_TRUE(isInRange(-43, 87u, -43)); + ASSERT_TRUE(isInRange(-43, 88u, -1)); + ASSERT_TRUE(isInRange(-43, 89u, 0)); + ASSERT_TRUE(isInRange(-43, 90u, 46)); + ASSERT_FALSE(isInRange(-43, 91u, 48)); + ASSERT_FALSE(isInRange(-43, 92u, 50)); + + ASSERT_FALSE(isInRange(43, 86u, 42)); + ASSERT_TRUE(isInRange(43, 87u, 43)); + ASSERT_TRUE(isInRange(43, 88u, 44)); + ASSERT_TRUE(isInRange(43, 89u, 131)); + ASSERT_FALSE(isInRange(43, 90u, 133)); + ASSERT_FALSE(isInRange(43, 91u, 135)); + + ASSERT_FALSE(isInRange(43u, 86u, 42u)); + ASSERT_TRUE(isInRange(43u, 85u, 43u)); + ASSERT_TRUE(isInRange(43u, 84u, 44u)); + ASSERT_TRUE(isInRange(43u, 83u, 125u)); + ASSERT_FALSE(isInRange(43u, 82u, 125u)); + ASSERT_FALSE(isInRange(43u, 81u, 125u)); + + ASSERT_FALSE(isInRange(-43, ~0u, 43)); + ASSERT_FALSE(isInRange(-43, ~0u, 44)); + ASSERT_FALSE(isInRange(-43, ~0u, ~0)); + ASSERT_FALSE(isInRange(-43, ~0u, 41)); + ASSERT_FALSE(isInRange(-43, ~0u, 40)); + + ASSERT_FALSE(isInRange(43u, ~0u, 43u)); + ASSERT_FALSE(isInRange(43u, ~0u, 41u)); + ASSERT_FALSE(isInRange(43u, ~0u, 40u)); + ASSERT_FALSE(isInRange(43u, ~0u, ~0u)); + + ASSERT_FALSE(isInRange(-43, 86u, -44, 0u)); + ASSERT_FALSE(isInRange(-43, 86u, -44, 1u)); + ASSERT_FALSE(isInRange(-43, 86u, -44, 2u)); + ASSERT_FALSE(isInRange(-43, 86u, -44, ~0u)); + ASSERT_TRUE(isInRange(-43, 87u, -43, 0u)); + ASSERT_TRUE(isInRange(-43, 87u, -43, 1u)); + ASSERT_TRUE(isInRange(-43, 87u, -43, 86u)); + ASSERT_TRUE(isInRange(-43, 87u, -43, 87u)); + ASSERT_FALSE(isInRange(-43, 87u, -43, 88u)); + ASSERT_FALSE(isInRange(-43, 87u, -43, ~0u)); + ASSERT_TRUE(isInRange(-43, 88u, -1, 0u)); + ASSERT_TRUE(isInRange(-43, 88u, -1, 45u)); + ASSERT_TRUE(isInRange(-43, 88u, -1, 46u)); + ASSERT_FALSE(isInRange(-43, 88u, -1, 47u)); + ASSERT_FALSE(isInRange(-43, 88u, -1, ~3u)); + ASSERT_TRUE(isInRange(-43, 90u, 46, 0u)); + ASSERT_TRUE(isInRange(-43, 90u, 46, 1u)); + ASSERT_FALSE(isInRange(-43, 90u, 46, 2u)); + ASSERT_FALSE(isInRange(-43, 91u, 48, 0u)); + ASSERT_FALSE(isInRange(-43, 91u, 48, 2u)); + ASSERT_FALSE(isInRange(-43, 91u, 48, ~6u)); + ASSERT_FALSE(isInRange(-43, 92u, 50, 0u)); + ASSERT_FALSE(isInRange(-43, 92u, 50, 1u)); + + ASSERT_FALSE(isInRange(43u, 86u, 42u, 0u)); + ASSERT_FALSE(isInRange(43u, 86u, 42u, 1u)); + ASSERT_FALSE(isInRange(43u, 86u, 42u, 2u)); + ASSERT_FALSE(isInRange(43u, 86u, 42u, ~0u)); + ASSERT_TRUE(isInRange(43u, 87u, 43u, 0u)); + ASSERT_TRUE(isInRange(43u, 87u, 43u, 1u)); + ASSERT_TRUE(isInRange(43u, 87u, 43u, 86u)); + ASSERT_TRUE(isInRange(43u, 87u, 43u, 87u)); + ASSERT_FALSE(isInRange(43u, 87u, 43u, 88u)); + ASSERT_FALSE(isInRange(43u, 87u, 43u, ~0u)); + ASSERT_TRUE(isInRange(43u, 88u, 60u, 0u)); + ASSERT_TRUE(isInRange(43u, 88u, 60u, 70u)); + ASSERT_TRUE(isInRange(43u, 88u, 60u, 71u)); + ASSERT_FALSE(isInRange(43u, 88u, 60u, 72u)); + ASSERT_FALSE(isInRange(43u, 88u, 60u, ~3u)); + ASSERT_TRUE(isInRange(43u, 90u, 132u, 0u)); + ASSERT_TRUE(isInRange(43u, 90u, 132u, 1u)); + ASSERT_FALSE(isInRange(43u, 90u, 132u, 2u)); + ASSERT_FALSE(isInRange(43u, 91u, 134u, 0u)); + ASSERT_FALSE(isInRange(43u, 91u, 134u, 2u)); + ASSERT_FALSE(isInRange(43u, 91u, 134u, ~6u)); + ASSERT_FALSE(isInRange(43u, 92u, 136u, 0u)); + ASSERT_FALSE(isInRange(43u, 92u, 136u, 1u)); + ASSERT_EQ(periodicError(124, 100), 24); ASSERT_EQ(periodicError(288, 100), 12); ASSERT_EQ(periodicError(-345, 100), 45); -- cgit v1.1