Exploit-DB #41983
Description: LG G4 MRA58K - 'mkvparser::Block::Block' Heap Buffer Overflow
Type: dos
Platform: android
Date: 2017-05-09
Author: Google Security Research

Exploit:
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1124

There are multiple paths in mkvparser::Block::Block(...) that result in heap buffer overflows. See attached for sample files that trigger the overflow conditions - these will not reliably crash the process, since the overflows are small and don't deterministically corrupt interesting data.

All offsets correspond to the version of the library I have, with md5sum 6708b7a76313c0a51df34c3cec5a0e0d.

Attached are crashers for the testcases which repeatedly cause the parsing of the files by the mediaserver process (via binder ipc), which will eventually cause the mediaserver to crash when the corrupted data is used.

1) (000035.mkv) Writing outside the bounds of a new[0] allocation. 

In mkvparser::Block::Block, there is a call to new[] (0xfd44) with an attacker controlled count. By setting this count to 0, this will be passed by _Znaj/_Znwj as a call to malloc(1). In jemalloc, this will result in a minimum-sized allocation of 8 bytes.

The result of this new[] call is stored in the mkvparser::Block structure at offset 0x1c, and if we take the path resulting in a call to mkvparser::Block::BlockWithEbml (0xfe50), this function will write into this allocation at an offset of 8, overwriting the dword immediately following the allocation (0xfb54).

Due to the behaviour of jemalloc, this will be the first dword of another allocation of size 8.

Build fingerprint: 'lge/p1_global_com/p1:6.0/MRA58K/[PII_REDACTED]d45:user/release-keys'
Revision: '11'
AM write failed: Broken pipe
ABI: 'arm'
pid: 14682, tid: 14791, name: Binder_2  >>> /system/bin/mediaserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xe3617e2e
    r0 f153f250  r1 f003f4e8  r2 00000000  r3 e3617e22
    r4 f003f500  r5 f153f250  r6 f003f4e8  r7 f1a59d58
    r8 f05008f4  r9 00000000  sl 000003f5  fp f050081c
    ip f6680e04  sp f05006a0  lr f667800b  pc f714f742  cpsr 600f0030

backtrace:
    #00 pc 0000e742  /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+33)
    #01 pc 00008007  /system/lib/libLGCodecParserUtils.so (_ZN7android20MediaExtractorHelperD2Ev+22)
    #02 pc 0000801d  /system/lib/libLGCodecParserUtils.so (_ZN7android20MediaExtractorHelperD0Ev+4)
    #03 pc 0000e753  /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+50)
    #04 pc 000273f1  /system/lib/libLGParserOSAL.so (_ZN7android14LGMKVExtractorD1Ev+124)
    #05 pc 00027425  /system/lib/libLGParserOSAL.so (_ZN7android14LGMKVExtractorD0Ev+4)
    #06 pc 0000e753  /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+50)
    #07 pc 000d64af  /system/lib/libstagefright.so (_ZN7android28StagefrightMetadataRetrieverD1Ev+118)
    #08 pc 000d6515  /system/lib/libstagefright.so (_ZN7android28StagefrightMetadataRetrieverD0Ev+4)
    #09 pc 0000e753  /system/lib/libutils.so (_ZNK7android7RefBase9decStrongEPKv+50)
    #10 pc 00058ee5  /system/lib/libmediaplayerservice.so (_ZN7android23MetadataRetrieverClient10disconnectEv+24)
    #11 pc 0008e19d  /system/lib/libmedia.so (_ZN7android24BnMediaMetadataRetriever10onTransactEjRKNS_6ParcelEPS1_j+72)
    #12 pc 00019931  /system/lib/libbinder.so (_ZN7android7BBinder8transactEjRKNS_6ParcelEPS1_j+60)
    #13 pc 0001eccb  /system/lib/libbinder.so (_ZN7android14IPCThreadState14executeCommandEi+550)
    #14 pc 0001ee35  /system/lib/libbinder.so (_ZN7android14IPCThreadState20getAndExecuteCommandEv+64)
    #15 pc 0001ee99  /system/lib/libbinder.so (_ZN7android14IPCThreadState14joinThreadPoolEb+48)
    #16 pc 00023909  /system/lib/libbinder.so
    #17 pc 000100d1  /system/lib/libutils.so (_ZN7android6Thread11_threadLoopEPv+112)
    #18 pc 0003f9ab  /system/lib/libc.so (_ZL15__pthread_startPv+30)
    #19 pc 0001a0c5  /system/lib/libc.so (__start_thread+6)

2) (000038.mkv) Writing outside the bounds of a new[16] allocation.

Following a similar path through the code, but instead letting the count resolve to 1, we get an allocation of size 16. We will then write outside the bounds of this allocation in mkvparser::Block::BlockWithEbml at (0xfbe0).

Build fingerprint: 'lge/p1_global_com/p1:6.0/MRA58K/[PII_REDACTED]d45:user/release-keys'
Revision: '11'
ABI: 'arm'
pid: 16410, tid: 16516, name: Binder_2  >>> /system/bin/mediaserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x6ec
    r0 000006ec  r1 f06dd3fc  r2 00000002  r3 efba11c4
AM write failed: Broken pipe
    r4 00000000  r5 00000800  r6 f19cf6c0  r7 00000800
    r8 00000000  r9 00000812  sl efba12e0  fp 00001000
    ip 00000000  sp f06dd410  lr 00000001  pc f6f31cb8  cpsr 200f0030

backtrace:
    #00 pc 00093cb8  /system/lib/libstagefright.so (_ZN7android18CallbackDataSource6readAtExPvj+39)
    #01 pc 00093e97  /system/lib/libstagefright.so (_ZN7android15TinyCacheSource6readAtExPvj+230)
    #02 pc 000262c9  /system/lib/libLGParserOSAL.so (_ZN19LGDataSourceAdaptor4ReadEPhPm+28)
    #03 pc 00014737  /system/lib/liblg_parser_mkv.so (_ZN9MkvReader4ReadExlPh+62)
    #04 pc 0000e1ed  /system/lib/liblg_parser_mkv.so (_ZN9mkvparser7Segment17DoLoadClusterInfoERxRlS1_S1_+212)
    #05 pc 00013c71  /system/lib/liblg_parser_mkv.so (_ZN9mkvparser7Segment13DoLoadClusterERxRl+140)
    #06 pc 00013e43  /system/lib/liblg_parser_mkv.so (_ZN9mkvparser7Segment11LoadClusterERxRl+14)
    #07 pc 0000aa73  /system/lib/liblg_parser_mkv.so (_ZN13BlockIterator3eosEv+42)
    #08 pc 0000b16f  /system/lib/liblg_parser_mkv.so (_ZN13BlockIterator7advanceEv+66)
    #09 pc 0000b765  /system/lib/liblg_parser_mkv.so (_ZN8MkvTrackC2EP12MkvExtractorm+164)
    #10 pc 0000b7d9  /system/lib/liblg_parser_mkv.so (_ZN12MkvExtractor8addTrackEm+24)
    #11 pc 00009c81  /system/lib/liblg_parser_mkv.so (_ZN9MKVParser8GetTrackEi+8)
    #12 pc 00009dc1  /system/lib/liblg_parser_mkv.so (_ZN9MKVParser4OpenEP11IDataSource+248)
    #13 pc 000271f9  /system/lib/libLGParserOSAL.so (_ZN7android14LGMKVExtractorC2ERKNS_2spINS_10DataSourceEEE+200)
    #14 pc 00022