When parsing a specialy crafted PDF document, a NULL pointer dereference leading to a process termination. A pointer value from a memory structure initialized to zero is reference without check.
Oracle Outside In IX SDK 8.5.1
While executing a
Tj operator on a piece of text contained in a stream, a memory structure
probably containing charset mappings is referenced. No NULL pointer check is made and
since the sturcture is zero initialized this can result in a crash.
The supplied testcase succesfully crashes the sample
supplied with the SDK.
In the supplied testcase, after the parser successfully decodes the /FlateDecode encoded stream data, it proceeds to execute the operators contained whitin. In this case the decoded stream data is :
'BT\r/F2 1 Tf\r12 0 0 12 90.001 708.017 Tm\r0 g\r/GS1 gs\r0 Tc\r0 Tw\r(Results)Tj\r/F3 1 Tf\r0 -1.04 TD\r0.0009 Tc\r0.0087 Tw\r(The tasters s'
The problematic code is triggered while
Tj operator is being executed with it’s
argument being string “Results”. Function
OIT_cmdTj in libvs_pdf.so implements
Eventually the function
sub_B74E190C is reached (libvs_pdf.so base address being 0xB74BF000)
and the crash is triggered by the following basic block specifically:
.text:B74E1E20 mov edx, [esp+0BCh+arg_4] .text:B74E1E27 movzx eax, byte ptr [edx+1F9Ch] .text:B74E1E2E mov edx, ebp  .text:B74E1E30 movzx ecx, dl  .text:B74E1E33 shl eax, 5 .text:B74E1E36 mov edi, [esp+0BCh+arg_4] .text:B74E1E3D lea edx, [eax+edi] .text:B74E1E40 mov eax, [edx+1F18h]  .text:B74E1E46 movzx edi, byte ptr [eax+ecx]  .text:B74E1E4A mov eax, edi .text:B74E1E4C test al, al .text:B74E1E4E jz loc_B7
At the time of the crash, initial value of
ebp at  contains the first character of the
Tj operator argument, in this case “R”, which ends up
ecx and is subsequently used as an offset into the memory structure at . At , value of
dl is zero extended into ecx limiting our control over it.
At , final value of
eax is set from offset 0x1f18 into
eax can be NULL but isn’t checked resulting in a near NULL
It is worth nothing that when the same memory address is accessed in other parts of the code, the pointer is properly checked beforehand.
2016-04-12 - Discovery
2016-07-19 – Public Disclosure
Discovered by Aleksandar Nikolic of Cisco Talos.