New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 2 users
Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Apr 2015
Cc:



Sign in to add a comment
Adobe Flash stack corruption when decoding JPEG-XR image
Project Member Reported by scvitti@google.com, Mar 16 2015 Back to list
Adobe Flash supports decoding of JPEG-XR images. This functionality is enabled by default. Diving into the function _jxr_r_MB_LP there is a stack overflow when indexing into an integer array. The flash code for this appears to closely match the ITU reference implementation (http://www.itu.int/rec/T-REC-T.835-201201-I/en) so I will reference that C code here to show the vulnerability:

file r_parse.c in function _jxr_r_MB_LP:
    0        int RLCoeffs[32] = {0};
    1        ...
    2        int num_nonzero = 0;
    3        ...
    4        num_nonzero = r_DECODE_BLOCK(image, str,
    5            chroma_flag, RLCoeffs, 1/*LP*/, location);
    6        
    7        DEBUG(" : num_nonzero = %d\n", num_nonzero);
    8        assert(num_nonzero <= 16);
    9
    10       if ((image->use_clr_fmt==1 || image->use_clr_fmt==2) && chroma_flag) {
    11           static const int remap_arr[] = {4, 1, 2, 3, 5, 6, 7};
    12           int temp[14];
    13           int idx;
    14           for (idx = 0 ; idx < 14 ; idx += 1)
    15               temp[idx] = 0;
    16 
    17           int remap_off = 0;
    18           if (image->use_clr_fmt==1/*YUV420*/)
    19               remap_off = 1;
    20
    21           int count_chr = 14;
    22           if (image->use_clr_fmt==1/*YUV420*/)
    23               count_chr = 6;
    24
    25           int k, i = 0;
    26           for (k = 0; k < num_nonzero; k+=1) {
    27               i += RLCoeffs[k*2+0];
    28               temp[i] = RLCoeffs[k*2+1];
    29               i += 1;
    30           }
    31       ...

On line 12 an integer array named temp is declared on the stack with 14 elements. On line 26 that integer array is populated in a for loop running from 0 to a maximum value of 16 iterations. The flash binary shows there is an explicit check on line 8 to bound num_nonzero to <= 16. On it's face this loop could write 2 integers beyond the end of the temp stack buffer. The last available index into tmp is 13 and the loop can write to index 14 and 15 just following the i+=1 on line 29.

However, it's worse than that due to the fact that the i variable increases not just by 1 each time through the loop but also by another user supplied value on line 27! The RLCoeffs array is populated with user data on line 4 with the r_DECODE_BLOCK function.

The stack frame for this function looks like this:

...
-000000BC RLCoeffs        dd 32 dup(?)
-0000003C temp            dd 14 dup(?)
-00000004 cookie          dd ?
+00000000  s              db 4 dup(?)
+00000004  r              db 4 dup(?)
+00000008 image           dd ?  
...

Compiler settings are good with the arrays at the end of the stack and a canary value between them and the saved ebp and return address. However, because we are writing to the stack non-sequentially it's possible to hop over the stack cookie and corrupt other bits of the stack.

PoC attached.

There are three files:
  LoadImg.as  - Action Script that will load the file img.img
  LoadImg.swf - Compiled LoadImg.as file
  img.img     - proof of concept JPEG-XR to exercise the vulnerability

When loading LoadImg.swf through Chrome flash will request and load the img.img file. The vulnerabile function is hit when the image is being decoded. It is called multiple times but the one that exercises the stack corruption will set num_nonzero to 8 and will then index out of bounds of the temp array to hop over the stack canary to corrupt saved ebp with a negitive value. A crash will occur two instructions after _jxr_r_MB_LP returns in Windows 7 32-bit running Chrome 41.0.2272.89:

63bd26dc e80e47ffff      call    pepflashplayer!PPP_ShutdownBroker+0x4d5bfc (63bc6def) ; _jxr_r_MB_LP
63bd26e1 83c410          add     esp,10h
63bd26e4 ff75f4          push    dword ptr [ebp-0Ch]  ss:0023:ffffffef=????????

eax=0716a340 ebx=0716a000 ecx=50b3cf2a edx=00000000 esi=0716a80c edi=001ad16c
eip=63bd26e4 esp=001ad0e4 ebp=fffffffb iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206
pepflashplayer!PPP_ShutdownBroker+0x4e14f1:
63bd26e4 ff75f4          push    dword ptr [ebp-0Ch]  ss:0023:ffffffef=????????

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.
 
img.img
504 bytes Download
LoadImg.swf
881 bytes Download
LoadImg.as
785 bytes Download
Project Member Comment 1 by scvitti@google.com, Mar 17 2015
Labels: ID-3493
Project Member Comment 2 by scvitti@google.com, Apr 2 2015
Owner: scvitti@google.com
Comment 3 by cevans@google.com, Apr 10 2015
Labels: CVE-2015-0350
Project Member Comment 5 by scvitti@google.com, Apr 22 2015
Labels: -Restrict-View-Commit
Sign in to add a comment