Re: Reading PNG Blob images causes access violation on png.c

Bob Friesenhahn <[email protected]> Tue, 30 Oct 2018 15:34:28 -0500 (CDT)
Newsgroups gmane.comp.video.graphicsmagick.help
Message-ID <[email protected]>
On Tue, 30 Oct 2018, Antti Luoma wrote:

> Hi,
>
> 1) I haven't tried this actually very much without our memory handling.
> First when I today tried I got system abort() call from Magick as Magick
> signature was 0, which was strange ( I had few questionable code lines also
> so maybe that has something to do with it.). But after using the default
> memory allocations I was actually able to read PNG blob without access
> violation. This is really good news as I have tried quite many things
> already but not this it seems. I should also note that reading jpg/bmb/tiff
> pictures works with our memory routines.

As a safeguard, the signature fields are set to zero when a structure 
is freed.  If there is an assertion due to a value of zero, that 
implies use of a structure which was already freed.

> Now I am wondering what in our memory routines is causing this access
> violation. Only thing which makes me wonder most is the fact that we use
> our session pointer as a context variable. We store this variable in
> ThreadLocalStorage and retrieve it from there (TlsGetValue()) before memory
> allocation as usually memory is pre-allocated and we just mark it as
> reserved. This is my guess that what could go wrong here but I don't know
> if I have understood setjmp/longjmp enough.

If it helps, the allocator that GraphicsMagick uses by default is 
based on the standard C library's malloc()/free() ("heap memory"). 
This helps when exchanging a buffer with some other library which 
expects that a buffer was allocated using malloc().  Windows does 
provide ways to allocate memory besides malloc().

I have heard that when DLLs are used that memory allocated by a DLL 
must be freed by the same DLL.

Setjmp/longjump works by restoring thread stack memory and registers 
to the values which were present when setjmp() is called.  It is 
pretty dangerous but it its use is demanded by libpng and libjpeg 
other than using a worker thread and thread cancellation, or a true 
exception mechanism (similar to C++).  It may be that use of 
setjmp/longjmp with threads is safer than what was originally assumed 
in GraphicsMagick but there are still dangers.

> 2) When reading png images the semaphore that was not released was the
> png.c own static one. There was other places as well but I have to get back
> on this later and be more specific.

We need to find out the exact exception case which resulted in this 
problem.  The png.c code is very complex and a great many problems 
have been fixed already with releasing resources when an error is 
reported.  The semaphore would be a resource to be released just like 
memory, or closing libpng handles.

> I also tried to define SETJMP_IS_THREAD_SAFE some day but I got some
> concurrency errors but those could also be related to the setjmp issue so I
> will have continue to work on this and I will report if there are issues
> that should checked. I have configured logging for stdout.

Exploring this issue is interesting to me.  The semaphore 
single-threads use of libpng as well as protecting against any 
potential harm due to setjmp/longjmp.

> We use checks/guards for our own semaphores so that if exception happens in
> some client session we check are all the semaphores released for this
> session (with a session id) and try to release those so that we don't cause
> permanent locks for shared resources.

It sounds like you may be using C++ where automated cleanup like this 
is possible.

Bob
-- 
Bob Friesenhahn
[email protected], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer,    http://www.GraphicsMagick.org/