New issue
Advanced search Search tips
Starred by 2 users
Status: Fixed
Owner:
Closed: Oct 2015
Cc:



Sign in to add a comment
Android libstagefright heap buffer overflow due to integer overflow in MP3 ID3 tag parsing
Project Member Reported by ianbeer@google.com, Aug 12 2015 Back to list
The following code is invoked when parsing ID3V2.4 tags in the android media server (taken from: https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/id3/ID3.cpp )

bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) {
    size_t oldSize = mSize;
    size_t offset = 0;
    while (offset + 10 <= mSize) {
        if (!memcmp(&mData[offset], "\0\0\0\0", 4)) {
            break;
        }
        size_t dataSize;
        if (iTunesHack) {
            dataSize = U32_AT(&mData[offset + 4]);        <-- (A)
        } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) {
            return false;
        }
        if (offset + dataSize + 10 > mSize) {                   <-- (B)
            return false;
        }
        uint16_t flags = U16_AT(&mData[offset + 8]);
        uint16_t prevFlags = flags;
        if (flags & 1) {
            // Strip data length indicator
            memmove(&mData[offset + 10], &mData[offset + 14], mSize - offset - 14);
            mSize -= 4;
            dataSize -= 4;
            flags &= ~1;
        }
        if (flags & 2) {
            // This file has "unsynchronization", so we have to replace occurrences
            // of 0xff 0x00 with just 0xff in order to get the real data.
            size_t readOffset = offset + 11;
            size_t writeOffset = offset + 11;
            for (size_t i = 0; i + 1 < dataSize; ++i) {   <-- (C)
                if (mData[readOffset - 1] == 0xff
                        && mData[readOffset] == 0x00) {
                    ++readOffset;
                    --mSize;
                    --dataSize;
                }
                mData[writeOffset++] = mData[readOffset++];
            }


At point (A) we read a controlled 32 bit value from the MP3. At (B) we can pass the check by providing a sufficiently large value for dataSize such that offset + dataSize + 10 overflows. Then at point (C) the large dataSize value is used as the terminating condition for a memory copying loop. By ensuring that the file does contain sequences of 0xff 0x00 bytes we can make sure that the copy is indeed modifying memory.

PoC attached. Tested on Nexus 6 and Android One both running Lollipop 5.1.1
 
tag_modified.mp3
180 KB Download
Project Member Comment 1 by ianbeer@google.com, Aug 12 2015
adb logcat output from Android One device:

I/DEBUG   (  142): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  142): Build fingerprint: 'google/Mi-498/Mi-498_sprout:5.1.1/LMY48K/2127894:user/release-keys'
I/DEBUG   (  142): Revision: '0'
I/DEBUG   (  142): ABI: 'arm'
I/DEBUG   (  142): pid: 145, tid: 572, name: Binder_2  >>> /system/bin/mediaserver <<<
I/DEBUG   (  142): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xb7d38000
W/NativeCrashListener(  511): Couldn't find ProcessRecord for pid 145
I/DEBUG   (  142):     r0 00068865  r1 b7ccf060  r2 00000000  r3 00068fa0
E/DEBUG   (  142): AM write failure (32 / Broken pipe)
I/DEBUG   (  142):     r4 b4768aa0  r5 00000000  r6 0000fffe  r7 00000004
I/DEBUG   (  142):     r8 0000b535  r9 00000001  sl 00000008  fp 0000ffff
I/DEBUG   (  142):     ip fffff8c0  sp b47689a0  lr 0006885b  pc b675f9ce  cpsr 80000030
I/DEBUG   (  142): 
I/DEBUG   (  142): backtrace:
I/DEBUG   (  142):     #00 pc 000c69ce  /system/lib/libstagefright.so (android::ID3::removeUnsynchronizationV2_4(bool)+225)
I/DEBUG   (  142):     #01 pc 000c6b6b  /system/lib/libstagefright.so (android::ID3::parseV2(android::sp<android::DataSource> const&, long long)+290)
I/DEBUG   (  142):     #02 pc 000c7443  /system/lib/libstagefright.so (android::ID3::ID3(android::sp<android::DataSource> const&, bool, long long)+26)
I/DEBUG   (  142):     #03 pc 00071f51  /system/lib/libstagefright.so (android::MP3Extractor::MP3Extractor(android::sp<android::DataSource> const&, android::sp<android::AMessage> const&)+624)
I/DEBUG   (  142):     #04 pc 000888c3  /system/lib/libstagefright.so (android::MediaExtractor::Create(android::sp<android::DataSource> const&, char const*)+214)
I/DEBUG   (  142):     #05 pc 00098e2b  /system/lib/libstagefright.so (android::StagefrightMetadataRetriever::setDataSource(int, long long, long long)+122)
I/DEBUG   (  142):     #06 pc 000421d9  /system/lib/libmediaplayerservice.so (android::MetadataRetrieverClient::setDataSource(int, long long, long long)+220)
I/DEBUG   (  142):     #07 pc 00063f23  /system/lib/libmedia.so (android::BnMediaMetadataRetriever::onTransact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+414)
I/DEBUG   (  142):     #08 pc 0001a6cd  /system/lib/libbinder.so (android::BBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+60)
I/DEBUG   (  142):     #09 pc 0001f77b  /system/lib/libbinder.so (android::IPCThreadState::executeCommand(int)+582)
I/DEBUG   (  142):     #10 pc 0001f89f  /system/lib/libbinder.so (android::IPCThreadState::getAndExecuteCommand()+38)
I/DEBUG   (  142):     #11 pc 0001f8e1  /system/lib/libbinder.so (android::IPCThreadState::joinThreadPool(bool)+48)
I/DEBUG   (  142):     #12 pc 00023a57  /system/lib/libbinder.so
I/DEBUG   (  142):     #13 pc 000104e1  /system/lib/libutils.so (android::Thread::_threadLoop(void*)+112)
I/DEBUG   (  142):     #14 pc 00010051  /system/lib/libutils.so
I/DEBUG   (  142):     #15 pc 0001659f  /system/lib/libc.so (__pthread_start(void*)+30)
I/DEBUG   (  142):     #16 pc 000144cb  /system/lib/libc.so (__start_thread+6)
Project Member Comment 2 by ianbeer@google.com, Aug 12 2015
Labels: Reported-2015-Aug-11 Id-182510
Android security bug report: https://code.google.com/p/android/issues/detail?id=182510
Project Member Comment 3 by ianbeer@google.com, Aug 12 2015
Labels: -Id-182510 Id-23129786
Project Member Comment 4 by ianbeer@google.com, Oct 13 2015
Labels: CVE-2015-6604
Status: Fixed
Advisory: https://groups.google.com/forum/#!topic/android-security-updates/iv1BF0f0XY4
Project Member Comment 5 by ianbeer@google.com, Jan 27 2016
Labels: -Restrict-View-Commit
Sign in to add a comment