[cairo] [PATCH] win32: Attempt to solve a nasty use-after-free by the caller of clone_similar()

Owen Taylor otaylor at redhat.com
Thu Feb 26 12:47:03 PST 2009

On Thu, 2009-02-26 at 15:12 -0500, Jeff Muizelaar wrote:
> On Thu, Feb 26, 2009 at 01:42:04PM -0500, Owen Taylor wrote:
> > It would be instructive to me to have detail on the actual bug here. I
> > agree that if you clone_similar() a Win32 surface, you can get a pointer
> > to the ->image internal object, and that doesn't have a backreference to
> > the win32 surface.
> > 
> > But it's hard for me to see how that would create a problem, unless
> > someone was keeping the clone past the scope of the cairo operation.
> Here's what happens:
> src = a win32 surface without an associated image surface
> dest = an image surface
> src.acquire_source_image()
> 	- this creates a new win32 surface (temp_win32) with an associated image surface 
> 	  that the contents of src are BitBlt'd onto. The image surface
> 	  uses bits from CreateDIBSection()
> dest.clone_similar(temp_win32.image)
> 	- returns a new reference to temp_win32.image
> src.release_source_image(temp_win32)
> 	- destroys temp_win32
> 		- win32_finish will DeleteObject() the bits associated
> 		  with temp_win32.image
> at this point we have a reference to an image surface that has had it's
> bits deleted. This reference is used for compositing later on which
> causes a crash.

OK, clear. The cleanest fix (given the limitations of reference
counting) would be to have a reference counted helper structure with
just a refcount and the HBITMAP and reference that both from the win32
surface and the image surface.

In that way, either the public Win32 surface or the public Image surface
could go away and the other would still work. When both went away, the
bitmap would be deleted.

- Owen

More information about the cairo mailing list