Bug 570425

Summary: ghostscript double free and invalid read caused by embedded jbig2 data
Product: [Other] Security Response Reporter: Marc Schoenefeld <mschoene>
Component: vulnerabilityAssignee: Red Hat Product Security <security-response-team>
Status: CLOSED WONTFIX QA Contact:
Severity: low Docs Contact:
Priority: low    
Version: unspecifiedCC: security-response-team, twaugh
Target Milestone: ---Keywords: Security
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-08-21 23:50:47 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Marc Schoenefeld 2010-03-04 10:12:46 UTC
Created attachment 397775 [details]
PDF reproducer causing double free

This occurs with ghostscript-8.15.2-9.11.el5 

valgrind  gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pswrite "-sOutputFile=a.ps" -c save pop -f a3.pdf
==24143== Memcheck, a memory error detector.
==24143== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==24143== Using LibVEX rev 1658, a library for dynamic binary translation.
==24143== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==24143== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==24143== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==24143== For more details, rerun with: -v
==24143==
==24143== Invalid write of size 4
==24143==    at 0x295113A: jbig2_symbol_dictionary (in /usr/lib/libgs.so.8.15)
==24143==    by 0x295036E: jbig2_parse_segment (in /usr/lib/libgs.so.8.15)
==24143==    by 0x294B82C: jbig2_data_in (in /usr/lib/libgs.so.8.15)
[...] 


gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pswrite "-sOutputFile=a.ps" -c save pop -f a3.pdf
jbig2dec FATAL ERROR decoding image: runlength too large in export symbol table (-2 > 83 - 0)
 (segment 0x00)
*** glibc detected *** gs: double free or corruption (out): 0x0953d748 ***
======= Backtrace: =========
/lib/libc.so.6[0x558595]
/lib/libc.so.6(cfree+0x59)[0x5589d9]
/usr/lib/libgs.so.8[0x294b46d]
/usr/lib/libgs.so.8(jbig2_free+0x16)[0x294b036]
/usr/lib/libgs.so.8(jbig2_image_free+0x3f)[0x294f12f]
/usr/lib/libgs.so.8(jbig2_image_release+0x31)[0x294f171]
/usr/lib/libgs.so.8(jbig2_sd_release+0x3c)[0x29509dc]
/usr/lib/libgs.so.8(jbig2_symbol_dictionary+0xda6)[0x2951946]
/usr/lib/libgs.so.8(jbig2_parse_segment+0xbf)[0x295036f]
/usr/lib/libgs.so.8(jbig2_data_in+0x1ed)[0x294b82d]
/usr/lib/libgs.so.8(s_jbig2decode_make_global_ctx+0x83)[0x294afe3]
/usr/lib/libgs.so.8[0x294ab9b]
/usr/lib/libgs.so.8(gs_interpret+0x192c)[0x28cc16c]
/usr/lib/libgs.so.8[0x28c1615]
/usr/lib/libgs.so.8(gs_main_run_string_end+0x34)[0x28c18a4]
/usr/lib/libgs.so.8(gs_main_run_string_with_length+0x92)[0x28c1e42]
/usr/lib/libgs.so.8(gs_main_run_string+0x4a)[0x28c1e9a]
/usr/lib/libgs.so.8[0x28c2825]
/usr/lib/libgs.so.8[0x28c3069]
/usr/lib/libgs.so.8[0x28c3217]
/usr/lib/libgs.so.8(gs_main_init_with_args+0x372)[0x28c4b72]
/usr/lib/libgs.so.8(gsapi_init_with_args+0x34)[0x28c5c54]
gs(main+0xbc)[0x80487cc]
/lib/libc.so.6(__libc_start_main+0xdc)[0x504e9c]
gs[0x8048651]
======= Memory map: ========
00110000-00164000 r-xp 00000000 fd:00 574736     /usr/lib/libXt.so.6.0.0
00164000-00168000 rwxp 00054000 fd:00 574736     /usr/lib/libXt.so.6.0.0
00168000-00267000 r-xp 00000000 fd:00 570415     /usr/lib/libX11.so.6.2.0
00267000-0026b000 rwxp 000ff000 fd:00 570415     /usr/lib/libX11.so.6.2.0
0047c000-0047d000 r-xp 0047c000 00:00 0          [vdso]
004d1000-004eb000 r-xp 00000000 fd:00 491553     /lib/ld-2.5.so
004eb000-004ec000 r-xp 00019000 fd:00 491553     /lib/ld-2.5.so
004ec000-004ed000 rwxp 0001a000 fd:00 491553     /lib/ld-2.5.so
004ef000-0062e000 r-xp 00000000 fd:00 491560     /lib/libc-2.5.so
0062e000-0062f000 --xp 0013f000 fd:00 491560     /lib/libc-2.5.so
0062f000-00631000 r-xp 0013f000 fd:00 491560     /lib/libc-2.5.so
00631000-00632000 rwxp 00141000 fd:00 491560     /lib/libc-2.5.so
00632000-00635000 rwxp 00632000 00:00 0
00637000-00639000 r-xp 00000000 fd:00 491570     /lib/libdl-2.5.so
00639000-0063a000 r-xp 00001000 fd:00 491570     /lib/libdl-2.5.so
0063a000-0063b000 rwxp 00002000 fd:00 491570     /lib/libdl-2.5.so
0063d000-00662000 r-xp 00000000 fd:00 491689     /lib/libm-2.5.so
00662000-00663000 r-xp 00024000 fd:00 491689     /lib/libm-2.5.so
00663000-00664000 rwxp 00025000 fd:00 491689     /lib/libm-2.5.so
00666000-0067a000 r-xp 00000000 fd:00 491584     /lib/libpthread-2.5.so
0067a000-0067b000 r-xp 00013000 fd:00 491584     /lib/libpthread-2.5.so
0067b000-0067c000 rwxp 00014000 fd:00 491584     /lib/libpthread-2.5.so
0067c000-0067e000 rwxp 0067c000 00:00 0
00680000-00692000 r-xp 00000000 fd:00 565578     /usr/lib/libz.so.1.2.3
00692000-00693000 rwxp 00011000 fd:00 565578     /usr/lib/libz.so.1.2.3
00695000-006ad000 r-xp 00000000 fd:00 579144     /usr/lib/libcupsimage.so.2
006ad000-006ae000 rwxp 00017000 fd:00 579144     /usr/lib/libcupsimage.so.2
0079a000-0079c000 r-xp 00000000 fd:00 570413     /usr/lib/libXau.so.6.0.0
0079c000-0079d000 rwxp 00001000 fd:00 570413     /usr/lib/libXau.so.6.0.0
0079f000-007a4000 r-xp 00000000 fd:00 570414     /usr/lib/libXdmcp.so.6.0.0
007a4000-007a5000 rwxp 00004000 fd:00 570414     /usr/lib/libXdmcp.so.6.0.0
007b2000-007c1000 r-xp 00000000 fd:00 570420     /usr/lib/libXext.so.6.4.0
007c1000-007c2000 rwxp 0000e000 fd:00 570420     /usr/lib/libXext.so.6.4.0
00852000-00877000 r-xp 00000000 fd:00 570412     /usr/lib/libpng12.so.0.10.0
00877000-00878000 rwxp 00024000 fd:00 570412     /usr/lib/libpng12.so.0.10.0
009dd000-009e8000 r-xp 00000000 fd:00 491769     /lib/libgcc_s-4.1.2-20080825.so.1
009e8000-009e9000 rwxp 0000a000 fd:00 491769     /lib/libgcc_s-4.1.2-20080825.so.1
009eb000-00acb000 r-xp 00000000 fd:00 575739     /usr/lib/libstdc++.so.6.0.8
00acb000-00acf000 r-xp 000df000 fd:00 575739     /usr/lib/libstdc++.so.6.0.8
00acf000-00ad0000 rwxp 000e3000 fd:00 575739     /usr/lib/libstdc++.so.6.0.8
00ad0000-00ad6000 rwxp 00ad0000 00:00 0
00ad8000-00b13000 r-xp 00000000 fd:00 493046     /lib/libsepol.so.1
00b13000-00b14000 rwxp 0003b000 fd:00 493046     /lib/libsepol.so.1
00b14000-00b1e000 rwxp 00b14000 00:00 0
00b20000-00b36000 r-xp 00000000 fd:00 493047     /lib/libselinux.so.1
00b36000-00b38000 rwxp 00015000 fd:00 493047     /lib/libselinux.so.1
00b3a000-00b51000 r-xp 00000000 fd:00 575433     /usr/lib/libICE.so.6.3.0
00b51000-00b52000 rwxp 00016000 fd:00 575433     /usr/lib/libICE.so.6.3.0
00b52000-00b54000 rwxp 00b52000 00:00 0
00b56000-00b5e000 r-xp 00000000 fd:00 575515     /usr/lib/libSM.so.6.0.0
00b5e000-00b5f000 rwxp 00007000 fd:00 575515     /usr/lib/libSM.so.6.0.0
00b61000-00b82000 r-xp 00000000 fd:00 575732     /usr/lib/libjpeg.so.62.0.0
00b82000-00b83000 rwxp 00020000 fd:00 575732     /usr/lib/libjpeg.so.62.0.0
00d5a000-00d69000 r-xp 00000000 fd:00 493045     /lib/libresolv-2.5.so
00d69000-00d6a000 r-xp 0000e000 fd:00 493045     /lib/libresolv-2.5.so
00d6a000-00d6b000 rwxp 0000f000 fd:00 493045     /lib/libresolv-2.5.so
00d6b000-00d6d000 rwxp 00d6b000 00:00 0
00d88000-00d8a000 r-xp 00000000 fd:00 493048     /lib/libcom_err.so.2.1
00d8a000-00d8b000 rwxp 00001000 fd:00 493048     /lib/libcom_err.so.2.1
00d8d000-00d8f000 r-xp 00000000 fd:00 493044     /lib/libkeyutils-1.2.so
00d8f000-00d90000 rwxp 00001000 fd:00 493044     /lib/libkeyutils-1.2.so
00d92000-00dbf000 r-xp 00000000 fd:00 576704     /usr/lib/libgssapi_krb5.so.2.2
00dbf000-00dc0000 rwxp 0002d000 fd:00 576704     /usr/lib/libgssapi_krb5.so.2.2
00dc2000-00dca000 r-xp 00000000 fd:00 576701     /usr/lib/libkrb5support.so.0.1
00dca000-00dcb000 rwxp 00007000 fd:00 576701     /usr/lib/libkrb5support.so.0.1
00dcd000-00df2000 r-xp 00000000 fd:00 576702     /usr/lib/libk5crypto.so.3.1
00df2000-00df3000 rwxp 00025000 fd:00 576702     /usr/lib/libk5crypto.so.3.1
00fd4000-00fe4000 r-xp 00000000 fd:00 66638      /usr/lib/ghostscript/8.15/X11.so
00fe4000-00fe8000 rwxp 0000f000 fd:00 66638      /usr/lib/ghostscript/8.15/X11.so
023a4000-02437000 r-xp 00000000 fd:00 576703     /usr/lib/libkrb5.so.3.3
02437000-0243a000 rwxp 00092000 fd:00 576703     /usr/lib/libkrb5.so.3.3
027c9000-027d2000 r-xp 00000000 fd:00 493043     /lib/libcrypt-2.5.so
027dAborted

Comment 2 Tim Waugh 2010-03-04 14:41:00 UTC
Created attachment 397822 [details]
ghostscript-broken-symbol-table.patch

Patch for ghostscript-8.71.  Also applies (with offset) to 8.15.2.

Comment 3 Tim Waugh 2010-03-04 14:55:40 UTC
I think this would be pretty hard to exploit.  It has the effect of a buffer overrun by one element, a pointer.

The code where it happens is illustrated below.  The data that is written past the buffer is a pointer to newly-allocated memory (from jbig2_image_new):

      for (;;) {
          /* check for broken symbol table */
          if (NSYMSDECODED > params->SDNUMNEWSYMS)
            {
              /* todo: mem cleanup? */
              jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
                "No OOB signalling end of height class %d", HCHEIGHT);
              break;
            }
[...]
                  image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
                  if (image == NULL) {
                      jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
                                  "failed to allocate image storage");
                      return NULL;
                  }

                  code = jbig2_decode_generic_region(ctx, segment, &region_params,
                                                     as, image, GB_stats);
                  /* todo: handle errors */

==>               SDNEWSYMS->glyphs[NSYMSDECODED] = image;
[...]
          /* 6.5.5 (4c.iv) */
          NSYMSDECODED = NSYMSDECODED + 1;

      } /* end height class decode loop */