Incorrect use of setjmp in coders/png.c
"Alexander E. Patrakov" <[email protected]> Fri, 24 Jul 2009 12:14:02 +0600
| Newsgroups | gmane.comp.video.image-magick.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi,
The ReadOnePNGImage() function contains this code:
QuantumInfo
*quantum_info;
...
quantum_info = NULL;
if (setjmp(ping->jmpbuf))
{
/*
PNG image is corrupt.
*/
...
if (quantum_info != (QuantumInfo *) NULL)
quantum_info = DestroyQuantumInfo(quantum_info);
...
return(GetFirstImageInList(image));
}
...
/*
Convert PNG pixels to pixel packets.
*/
quantum_info=AcquireQuantumInfo(image_info,image);
/* use it, possibly call longjmp() ... */
quantum_info=DestroyQuantumInfo(quantum_info);
And here is a problem, because the longjmp() manual page says:
The values of automatic variables are unspecified after a call to
longjmp() if they meet all the following criteria:
o they are local to the function that made the corresponding setjmp(3)
call;
o their values are changed between the calls to setjmp(3) and
longjmp(); and
o they are not declared as volatile.
For quantum_info, all three conditions are true. And indeed, some gcc
versions decide to cache it in a register at the time when setjmp() is
called. So, when longjmp() restores that context, it also restores the
register where quantum_info is held (to NULL). Thus,
DestroyQuantumInfo is not called, and there is a memory leak
reproducible on linux, e.g., by passing an incompletely downloaded png
file to BlobToImage(). The same consideration applies to two more
variables.
So, for a quick fix, I propose to change three declarations, as follows:
Image
* volatile image;
QuantumInfo
* volatile quantum_info;
unsigned char
* volatile png_pixels;
--
Alexander E. Patrakov