|
|
LG: Missing bounds-checking in AVI stream parsing | ||
| Project Member Reported by markbrand@google.com, Mar 20 2017 | Back to list | ||
Missing bounds-checking in AVI stream parsing
When parsing AVI files, CAVIFileParser uses the stream count from the AVI header
to allocate backing storage for storing metadata about the streams (member
variable m_aStream). However, the number of stream headers we parse is never
validated against this allocation size during parsing, so we can write further
metadata past the end of this buffer by constructing a file which contains more
stream headers than expected.
The allocation happens here:
int CAVIFileParser::ParseChunkAviHdr(int a2, unsigned int chunk_size)
{
struct AviHeader *avih;
int result;
// snip some sanity checking (have we already found an 'avih' chunk, is this
// chunk large enough to contain an avi header.)
result = AVISourceReader::AVI_fread(this->source, avih, sizeof(struct AviHeader), 1);
if ( result <= 0 )
{
// snip...
}
else
{
stream_count = avih->dwStreams; // <-- this is an attacker-controlled count
this->m_aStreamCount = stream_count;
this->m_aStream = malloc(stream_count * sizeof(struct AviStream));
this->m_aStreamIndex = -1;
// snip...
}
return 1;
}
There doesn't appear to be any integer overflow checking in the multiplication
either; so if the current issue is directly fixed there could still be a
vulnerability if stream_count * sizeof(struct AviStream) overflows.
this->m_aStreamIndex is incremented without checking in
CAVIFileParser::ParseChild and used as an index into m_aStream in several places
without checking, including in CAVIFileParser::ParseChunkStrHdr and
CAVIFileParser::ParseChunkStrFmt.
Several of the values that we can get written out of bounds are pointers to
controlled data, which is an interesting exploitation primitive. I've attached
a PoC file and script to generate it which results in overlapping a SRIFFNode*
with the contents of a 'strf' chunk, resulting in a free of an attacker
controlled pointer - in this case, 0x41414141. Since the structure sizes are
dependent on the version of the library, this may not work on different builds,
but it will hopefully cause a crash regardless.
Build fingerprint: 'lge/p1_global_com/p1:6.0/MRA58K/1624210305d45:user/release-keys'
Revision: '11'
ABI: 'arm'
pid: 19481, tid: 19585, name: Binder_2 >>> /system/bin/mediaserver <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4140007c
r0 00000002 r1 00000012 r2 ffffffd0 r3 f6b572f0
AM write failed: Broken pipe
r4 f6b572e8 r5 41414141 r6 f5fb6000 r7 41400000
r8 f155c748 r9 f6b4a594 sl 00000001 fp f000081c
ip 41400048 sp f00005f8 lr f6b2c7a7 pc f6b29826 cpsr 200f0030
backtrace:
#00 pc 00055826 /system/lib/libc.so (ifree+49)
#01 pc 000587a3 /system/lib/libc.so (je_free+374)
#02 pc 000058f3 /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParser15DeleteSRIFFNodeEP9SRIFFNode+54)
#03 pc 00005915 /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParser7DestroyEv+12)
#04 pc 00005a33 /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParserD1Ev+14)
#05 pc 00005a45 /system/lib/liblg_parser_avi.so (_ZN14CAVIFileParserD0Ev+4)
#06 pc 0000442f /system/lib/liblg_parser_avi.so (_ZN9AVIParser5CloseEv+12)
#07 pc 00025baf /system/lib/libLGParserOSAL.so (_ZN7android14LGAVIExtractorD1Ev+26)
This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available, the bug report will become
visible to the public.
Project Member
Comment 1
by
markbrand@google.com,
Mar 20 2017
,
Jun 13
Derestricting as issue reported fixed in LG June Bulletins.
,
Jun 26
This seems to work on the current LG G6. Does anyone have an actual POC? we have been trying to gain root with an unlocked BL (LG took away fast boot) |
|||
| ► Sign in to add a comment | |||