LG MRA58K - Out-of-Bounds Heap Read in CAVIFileParser::Destroy Resulting in Invalid Free








Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1221

Similar to the previously reported  issue 1206 , when parsing AVI files the 
CAVIFileParser object contains a fixed-size array of (what appears to be)
pointer/length pairs, used (I suppose) to store the data for each stream.

This is a fixed size, with 40 entries. However, it is never verified that the
number of streams in the file is less than this number; and when freeing the 
CAVIFileParser object, we will iterate through this array past the end of the
object, freeing each non-NULL pointer entry.

This presents initially as a free of an uninitialised pointer, since there is
a correctly aligned field inside the CAVIFileParser object that does not appear
to be used at all; careful heap grooming can turn this into a free of an 
attacker controlled value. It can also however be used to traverse outside the
object by ensuring that this uninitialised value is a NULL pointer, and instead 
free pointers from the object following the CAVIFileParser object, resulting in
a use-after-free.

The attached sample file (and generation script) triggers the latter case, and 
will usually crash attempting to free an invalid pointer from outside the bounds
of the CAVIFileParser object.

The two quirks of the attached sample file necessary to reach this vulnerability
are that the number of streams in the avi are larger than 40 and that the file
is truncated before the strl LIST objects are completed, to avoid triggering a 
NULL-pointer dereference attempting to retrieve the movi information for the 

Build fingerprint: 'lge/p1_global_com/p1:6.0/MRA58K/1624210305d45:user/release-keys'
Revision: '11'
ABI: 'arm'
pid: 9473, tid: 9473, name: mediaserver  >>> /system/bin/mediaserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xf0040070
AM write failed: Broken pipe
    r0 00000002  r1 0000000f  r2 ffffffd0  r3 f6dd12f0
    r4 f6dd12e8  r5 f0051c88  r6 f6202000  r7 f0040000
    r8 f6209008  r9 f6dc4594  sl 00000001  fp ffc82f9c
    ip f004003c  sp ffc82d38  lr f6da67a7  pc f6da3826  cpsr 200f0030

    #00 pc 00055826  /system/lib/libc.so (ifree+49)
    #01 pc 000587a3  /system/lib/libc.so (je_free+374)
    #02 pc 000059ad  /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParser7DestroyEv+164)
    #03 pc 00005a33  /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParserD1Ev+14)
    #04 pc 00005a45  /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParserD0Ev+4)
    #05 pc 0000442f  /system/lib/liblg_parser_avi.so (_ZN9AVIParser5CloseEv+12)
    #06 pc 00025a49  /system/lib/libLGParserOSAL.so (_ZN7android14LGAVIExtractorC2ERKNS_2spINS_10DataSourceEEE+308)
    #07 pc 00022a67  /system/lib/libLGParserOSAL.so (_ZN7android15LGExtractorOSAL17CreateLGExtractorERKNS_2spINS_10DataSourceEEEPKcRKNS1_INS_8AMessageEEE+38)
    #08 pc 000c033b  /system/lib/libstagefright.so (_ZN7android14MediaExtractor6CreateERKNS_2spINS_10DataSourceEEEPKc+242)
    #09 pc 000d66db  /system/lib/libstagefright.so (_ZN7android28StagefrightMetadataRetriever13setDataSourceERKNS_2spINS_10DataSourceEEE+34)
    #10 pc 000591e3  /system/lib/libmediaplayerservice.so (_ZN7android23MetadataRetrieverClient13setDataSourceERKNS_2spINS_11IDataSourceEEE+82)
    #11 pc 0008e329  /system/lib/libmedia.so (_ZN7android24BnMediaMetadataRetriever10onTransactEjRKNS_6ParcelEPS1_j+468)
    #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 00001c15  /system/bin/mediaserver
    #17 pc 000174a9  /system/lib/libc.so (__libc_init+44)
    #18 pc 00001e68  /system/bin/mediaserver

Proof of Concept: