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
file.
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
backtrace:
#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:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/42169.zip