Bug 688075

Summary: GC segfault on encoded bitmap
Product: Ghostscript Reporter: Stephen McCamant <smcc>
Component: PS InterpreterAssignee: Alex Cherepanov <alex>
Status: RESOLVED DUPLICATE    
Severity: normal    
Priority: P2    
Version: master   
Hardware: PC   
OS: Linux   
Customer: Word Size: ---
Attachments: Example input that causes the segfault

Description Stephen McCamant 2005-05-05 14:17:23 UTC
When I try to display a PS file that contains a certain CCITT-encoded bitmap,
Ghostscript will reliably segfault slightly later in execution (at exit,
for a small example).

The crash also occurs when I try to view a PDF file containing the same 
image (the PS file was created from the PDF file with pstopdf). xpdf can
view the same PDF file without problems; acroread 5 displays some errors,
but does not crash. (The PDF file appears to have been generated with an
old version of Ghostscript, 5.03). Even if the image is somehow illegal,
though, I don't think Ghostscript should crash.

The crash is a null pointer dereference that occurs in garbage collection
code. Here's the backtrace:

#0  0x080fbc65 in gc_objects_clear_marks (mem=0x83d813c, cp=0x8541750)
    at src/igc.c:582
#1  0x080fae23 in gs_gc_reclaim (pspaces=0x83f9aa8, global=1) at src/igc.c:263
#2  0x081782d9 in context_reclaim (pspaces=0x83f9aa8, global=1)
    at src/zcontext.c:286
#3  0x080d0e54 in gs_vmreclaim (dmem=0x83f9aa4, global=1) at src/ireclaim.c:156
#4  0x080d0c4b in ireclaim (dmem=0x83f9aa4, space=8) at src/ireclaim.c:78
#5  0x080cba77 in interp_reclaim (pi_ctx_p=0x83d7eac, space=8)
    at src/interp.c:419
#6  0x080c353f in gs_main_finit (minst=0x83d7cd8, exit_status=0, code=0)
    at src/imain.c:834
#7  0x080c3804 in gs_to_exit_with_code (mem=0x83d7c40, exit_status=0, code=0)
    at src/imain.c:898
#8  0x0804b06c in main (argc=2, argv=0xbffff8b4) at src/gs.c:89

The line where the segfault occurs is:

582             struct_proc_clear_marks((*proc)) =

"proc" is 0. 

Here is an example file that causes the crash:

<<
  /ImageType 1
  /Width 41
  /Height 53
  /ImageMatrix [41 0 0 -53 0 53]
  /BitsPerComponent 1
  /DataSource currentfile
    /ASCII85Decode filter
    << /K -1 /Columns 41 >> /CCITTFaxDecode filter
>>
imagemask
21]lq#&Y.eV>*>aTe%\1$gV0p6i+[q#1HrT0jbH?+90%B)tk71OPn%E%#/K"RXiBX
+9Dl~>
%-EOD-

I've been able to reproduce this with all the Ghostscript versions I have
handy, ranging from 8.01 to today's CVS checkout.
Comment 1 Stefan Kemper 2005-05-05 15:21:40 UTC
Thanks could I get you to attach the test file as an attachment and give the
commandline you used to get it to fail.  Thanks.
Comment 2 Stephen McCamant 2005-05-05 16:49:28 UTC
Created attachment 1366 [details]
Example input that causes the segfault

To reproduce:

gs bug688075.ps </dev/null

where bug688075.ps is the attachment. In lieu of the "</dev/null", you
can also just signal end-of-file at the "GS>" prompt.
Comment 3 Alex Cherepanov 2005-05-07 04:04:49 UTC
I can reproduce the bug on peeves.ghostscript.com, GS 8.30, but I cannot
reproduce the bug on Windows XP under Cygwin (GCC 3.3.3) or MSVC6 executables.
Comment 4 Stephen McCamant 2005-05-10 20:10:23 UTC
I've done a little more basic investigation:

If I compile with debugging, the segfault happens in ialloc_validate_chunk
instead of gc_objects_clear_marks, but the relevant code looks similar:

314             struct_proc_enum_ptrs((*proc)) = pre->o_type->enum_ptrs;

I was previously mislead by the hairy macro that's getting expanded there;
I think the problem is actually not that proc is being dereferences as a null
pointer, but that the initialization of proc is accessing an out of bounds
pointer. The expanded code looks like:

proc = pre->d.o.t.type->enum_ptrs

but pre->d.o.t.type is a bogus value (0x933b080 here). With the help of a
watchpoint, I can see where it's getting corrupted, in cf_decode_2d:

693                 invert_data(dlen, black_byte, DO_NOTHING, idd);

This line changes the address later accessed as pre->d.o.t.type from
0x833b080 (which is a valid pointer) into the bad 0x933b080 value. I suspect
it's overrunning a buffer and treating part of a pointer as if it were
image data. ("dlen" is 42, which is one larger than the declared width of
the image.)

Does ghostscript support compiling in a "Purify" or "Valgrind" mode where it
uses plain old malloc() rather than its garbage collector? That might make
debugging this sort of problem easier.
Comment 5 leonardo 2007-08-07 13:00:06 UTC
It looks as a problem in scfd.c Passing to Alex who owns that module.
Comment 6 leonardo 2007-08-07 13:17:20 UTC
I think there is no need to reproduce segfault on Windows. Just see what 
happens while processing the filter. Likely it writes outside the buffer.
Comment 7 Alex Cherepanov 2008-07-28 17:44:21 UTC

*** This bug has been marked as a duplicate of 689917 ***