Bug 688140 - A heap corruption in imagemask
Summary: A heap corruption in imagemask
Status: NOTIFIED FIXED
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: General (show other bugs)
Version: master
Hardware: PC Windows XP
: P3 normal
Assignee: Igor Melichev
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-15 01:49 UTC by Igor Melichev
Modified: 2008-12-19 08:31 UTC (History)
0 users

See Also:
Customer:
Word Size: ---


Attachments
crash.bat (731 bytes, text/plain)
2005-06-15 02:01 UTC, Igor Melichev
Details
gsalloc.c (patched) (64.64 KB, text/plain)
2005-06-15 02:11 UTC, Igor Melichev
Details
trial patch1.txt (5.12 KB, text/plain)
2005-06-15 02:52 UTC, Igor Melichev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Igor Melichev 2005-06-15 01:49:30 UTC
This is a very delicate problem, which is hard to reproduce, because it 
depends on when garbager is invoked. Particularly I noticed that it depends on 
values of system environment variables (actually on their size). I'll attach a 
test case, but the probability of the reproduction in another machine or with 
another compiler is pretty small.

The reason for the problem is the code in gs_image_begin_typed and 
zimage_data_setup, which appear insufficiently compatible. The problem happens 
when imagemask is called in the global allocation mode and the current graphic 
state is a local object (Sic! I do observe that i_ctx_p->memory->current 
points to the global memory 0x003e5a18, and in same time i_ctx_p->pgs->memory 
points to the local memory 0x003e4fe0). gs_image_begin_typed creates an 
instance of gx_image_enum in the local memory (the pgs->memory), then 
zimage_data_setup creates another instance of gs_image_enum in 'imemory' 
(which is global), and sets the pointer penum->info from the second instanse 
to the first instance (actually it happens in gs_image_common_init called from 
gs_image_enum_init, which is called from zimage_data_setup). This pointer 
points from global memory to local memory, and therefore it is incorrect. Then 
zimage_data_setup places a pointer to the second instance onto estack. Note 
there are no other pointers to both instances. 

In the test case the local memory overflow happens immediately in 
the 'imagemask', therefore the garbager is being invoked to collect the local 
memory. It does not affect the global memory, and therefore the incorrect 
pointer is not relocated. After returning from the garbager the incorrect 
pointer points to an invalid address, and later it causes an access violation 
exception in ialloc_validate_object.
Comment 1 Igor Melichev 2005-06-15 01:57:58 UTC
I'm not sure how to fix it correctly. Placing both instances of gs_image_enum 
in the local memory should be preferrable, so probably zimage_data_setup must 
use i_ctx_p->pgs->memory instead iiemory. Also gs_image_begin_typed is hard to 
patch with adding the memory argument, because it is called from multiple 
places of the graphics library, so the change would distribute too wide and 
affects the device interface. So I thing patching zimage_data_setup and 
image_cleanup should be simpler.
Comment 2 Igor Melichev 2005-06-15 01:59:58 UTC
Created attachment 1448 [details]
temp2.ps

The sample document.
Comment 3 Igor Melichev 2005-06-15 02:01:16 UTC
Created attachment 1449 [details]
crash.bat

A script to reproduce.
Comment 4 Igor Melichev 2005-06-15 02:11:04 UTC
Created attachment 1450 [details]
gsalloc.c (patched)

A patched revision of gsalloc.c used to hook interesting allocations with MS
Developer Studio. The interesting allocation is i_alloc_struct called with
st_gx_image_enum. The instance address 0x18fd8b8 is hardcoded, but it may be
different in a different environment. The call ahppens with the image size
48x87 and after the allocation pinfo->id gets the value 97278, which may be
used to hook with a breakpoint at gdevvdrw.c ln 907 (in
gx_default_begin_typed_image after the call to *dev_proc(dev, begin_image) ).
Comment 5 Igor Melichev 2005-06-15 02:52:11 UTC
Created attachment 1451 [details]
trial patch1.txt
Comment 6 Igor Melichev 2005-06-15 10:36:46 UTC
The description of this bug includes some wrong statements, which are minor. 
When wrote it, I assumed that gs_image_enum is a subcalss of 
gx_image_enum_common_t. Actually it is not, and the mentioned instances have 
different types. The rest of the discription is correct.
Comment 7 Igor Melichev 2005-06-15 11:43:28 UTC
Patch to HEAD :
http://ghostscript.com/pipermail/gs-cvs/2005-June/005567.html