When parsing a specially crafted PDF document, the parser is expecting a pointer where string is located leading to a read access violation with a controlled source operand.
While parsing a malformed PDF file, with an object that contains malformed
/Kids reference, the value right after the /Kids element is interpreted as a string, where
an array of references should be located. This leads to parser expecting a pointer where
the string copied from the file is located resulting in an arbitrary read access violation.
In a properly formatted PDF file, an array of at least one reference must follow after
In the supplied testcase, an ASCII value after the /Kids element is placed on the heap and is later referenced by the parser, and wrongfully interpreted as a pointer. The bug appears in libvs_pdf.so (with base address 0x0xB74BF000):
.text:B74E71DB mov eax, [eax]  .text:B74E71DD mov edi, [esp+5Ch+var_24] .text:B74E71E1 mov eax, [eax+edi*4]  .text:B74E71E4 mov [esp+5Ch+var_4C], eax .text:B74E71E8 mov ecx, [esp+5Ch+var_34] .text:B74E71EC mov edx, [esp+5Ch+var_48]
eax points to the string copied from the file into the heap. First
four bytes of the string are used in the memory access calculation at 
causing an arbitrary ReadAV.
If the value calculated at  ends up pointing to valid memory, the read will succeed
at the controlled address. The read value is later again used as a pointer during a
If the value after the /Kids element is a pure integer, a different code path is reached and the integer value is interpreted as a pointer resulting in a fully controlled arbitrary read at:
.text:B74E718A mov eax, [esp+5Ch+var_18] .text:B74E718E mov eax, [eax] .text:B74E7190 xor edx, edx .text:B74E7192 mov edi, [eax+4]  .text:B74E7195 test edi, edi .text:B74E7197 jz loc_B74E72A2
eax at  in the above basic block is the integer value following
/Kids element in the file making a fully controlled arbitrary read.
Further more, the read value ends up being used as a pointer at the start of
the basic block mentioned first leading to a double controlled dereference.
With the integer value following the
/Kids element equal to 1094795585 (or 0x41414141)
the application crashes in the following way :
Program received signal SIGSEGV, Segmentation fault. 0xb74e7192 in ?? () from /home/ea/oit_pdf/sdk/demo/libvs_pdf.so Missing separate debuginfos, use: debuginfo-install libgcc-4.9.2-6.fc21.i686 libstdc++-4.9.2-6.fc21.i686 (gdb) exploitable Description: Access violation on source operand Short description: SourceAv (19/22) Hash: 9240766c9eb6b90a82dca46b72483f92.6ab7c7b29ce914720061150720510f77 Exploitability Classification: UNKNOWN Explanation: The target crashed on an access violation at an address matching the source operand of the current instruction. This likely indicates a read access violation. Other tags: AccessViolation (21/22) (gdb) x/i $pc => 0xb74e7192: mov edi,DWORD PTR [eax+0x4] (gdb) i r eax 0x41414141 1094795585 ecx 0x0 0 edx 0x0 0 ebx 0xb74f6998 -1219532392 esp 0xbfffdce0 0xbfffdce0 ebp 0xf 0xf esi 0x80a46f8 134891256 edi 0x809e7c0 134866880 eip 0xb74e7192 0xb74e7192 eflags 0x10246 [ PF ZF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb)
It is possible that by carefully setting the value of the initially dereferenced pointer, more interesting code paths could be reached and, coupled with other bugs, lead to further abuse.
2016-04-12 - Vendor Notification
2016-07-19 – Public Disclosure
Discovered by Aleksandar Nikolic of Cisco Talos.