php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29349 imagecreatefromstring segfaults (fix included)
Submitted: 2004-07-23 12:01 UTC Modified: 2004-07-31 18:42 UTC
Votes:3
Avg. Score:4.7 ± 0.5
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: k at ailis dot de Assigned:
Status: Closed Package: GD related
PHP Version: 4CVS-2004-07-23 (stable) OS: Linux
Private report: No CVE-ID: None
 [2004-07-23 12:01 UTC] k at ailis dot de
Description:
------------
imagecreatefromstring segfaults when using the external GD library. The bundled one works. As far as I understood this problem the imagecreatefromstring function calls gdNewDynamicCTX and this function frees some memory which don't have to be freed. Maybe this function was changed in the bundled GD library. But this is not needed. Instead of gdNewDynamicCtx the function gdNewDynamicCtxEx can be used. The additional third parameter must be 0 so the function doesn't free the memory. Doing in in that way imagecreatefromstring works again in the external GD library and also in the bundled one. Here is a small patch, but please take it with care. I don't really know what you are doing there with all these memory freeing hacks. Maybe my patch creates a memory leak. Don't know.


--- gd.c.orig   2004-07-23 11:24:51.000000000 +0200
+++ gd.c    2004-07-23 11:31:10.000000000 +0200
@@ -1274,7 +1274,7 @@
    gdImagePtr im;
    gdIOCtx *io_ctx;

-   io_ctx = gdNewDynamicCtx (Z_STRLEN_PP(data), Z_STRVAL_PP(data));
+   io_ctx = gdNewDynamicCtxEx (Z_STRLEN_PP(data), Z_STRVAL_PP(data), 0);

    if (!io_ctx) {
        return NULL;


Reproduce code:
---------------
Can't provide one. The bug seems to be very system dependend. It works on some machines. On others it don't. It works for some image files. With others it don't.

Expected result:
----------------
No segfault.

Actual result:
--------------
segfault ;-)

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-07-23 13:50 UTC] tony2001@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a backtrace to see what is happening behind the scenes. To
find out how to generate a backtrace, please read
http://bugs.php.net/bugs-generating-backtrace.php

Once you have generated a backtrace, please submit it to this bug
report and change the status back to "Open". Thank you for helping
us make PHP better.

Please, provide a gdb backtrace.
 [2004-07-23 14:09 UTC] k at ailis dot de
I have searched the closed bug reports and it looks like 
you will find the whole problem in #24174 (including a 
backtrace). Your solution was to modify the bundled GD 
library. In my opinion this is a very bad solution because 
this does not fix the problem if you use the external GD 
library. And it seems NOT to be a bug in GD! It's seems 
more like a misuse of a GD-function. The external GD 
library AND the bundled one can be used if you try my fix 
and check if it does not break something else. It looks to 
me that Boutell has created this *CtxEx function exactly 
for people who want to control the memory-freeing 
behaviour of the function so it might be the correct 
solution.
 [2004-07-24 14:05 UTC] adconrad at debian dot org
Note that gdNewDynamicCtxEx was added in 2.0.21, so if this is used unconditionally, PHP will need to depend on that version of libgd2.  (Also, this does appear to fix the segfaults being reported all over the place for imagecreatefromstring with the external libgd2)
 [2004-07-24 14:08 UTC] adconrad at debian dot org
Also note that gdNewDynamicCtx is used 3 times in gd.c, not just once as the patch would lead one to believe.
 [2004-07-25 15:21 UTC] adconrad at debian dot org
As of the next upload to the Debian archive, we will be using the following patch, which seems to clear up every php4-gd segfault bug we've had reported:

--- php4-4.3.8/ext/gd/gd.c.orig 2004-07-24 06:00:25.000000000 -0600
+++ php4-4.3.8/ext/gd/gd.c      2004-07-24 06:10:38.000000000 -0600
@@ -1242,7 +1242,7 @@
 #ifdef HAVE_GD_WBMP
        else {
                gdIOCtx *io_ctx;
-               io_ctx = gdNewDynamicCtx (8, data);
+               io_ctx = gdNewDynamicCtxEx (8, data, 0);
                if (io_ctx) {
                        if (getmbi((int(*)(void*))gdGetC, io_ctx) == 0 && skipheader((int(*)(void*))gdGetC, io_ctx) == 0 ) {
 #if HAVE_LIBGD204
@@ -1274,7 +1274,7 @@
        gdImagePtr im;
        gdIOCtx *io_ctx;

-       io_ctx = gdNewDynamicCtx (Z_STRLEN_PP(data), Z_STRVAL_PP(data));
+       io_ctx = gdNewDynamicCtxEx (Z_STRLEN_PP(data), Z_STRVAL_PP(data), 0);

        if (!io_ctx) {
                return NULL;
@@ -1428,7 +1428,7 @@
                        goto out_err;
                }

-               io_ctx = gdNewDynamicCtx(buff_size, buff);
+               io_ctx = gdNewDynamicCtxEx(buff_size, buff, 0);
                if(!io_ctx) {
                        php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot allocate GD IO context");
                        goto out_err;
 [2004-07-25 19:28 UTC] iliaa@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions. 

Thank you for your interest in PHP.

This is a bug in the GD library, we recommend to always use 
the bundled GD library, which as you've indicated does not 
have this problem. 
 [2004-07-25 20:54 UTC] k at ailis dot de
Narf... This is NOT a bug in the GD library. The function 
you are using is freeing memory because this function is 
MEANT to do exactly this because this function normally 
deals with data which was allocated by GD itself. But you 
are passing data to this function which was allocated by 
YOU. Boutell has already dealt with this problem and has 
created new functions which exactly suit your needs: The 
gdImageCreateFrom*Ptr functions and also the 
gdNewDynamicCtxEx function. RTFM: 
 
  * The new gdNewDynamicCtxEx function was added to 
support the easy 
       implementation of the above functions and to 
correct a design 
       problem which made life unpleasant for those 
passing in memory not 
       originally allocated by gd to the gdNewDynamicCtx 
function by 
       providing a way to specify that gd should never 
free or reallocate 
       a particular block of memory. The gdNewDynamicCtx 
function and its 
       relatives, although still exported for ABI 
compatibility, are now 
       deprecated except for internal use, in favor of 
       [45]gdImageCreateFromPngPtr and its relatives. 
 
So please stop putting your head in the sand and apply 
Adam Conrad's patch or move to the new 
gdImageCreateFrom*Ptr functions.
 [2004-07-25 21:10 UTC] iliaa@php.net
The patch relies on a function only available in later 
versions of GD, which not everyone has. The bundled GD has 
no problem what so over and should be used. 
 [2004-07-25 21:42 UTC] k at ailis dot de
Then why are you not modifying your configure system so it 
checks to have at least GD 2.0.21 if the external GD lib 
is used? If you are argumenting that everyone should use 
the bundled GD lib anyway then you don't need to bother 
with those poor users which are not having at least GD 
2.0.21. 
 
But if you don't want to "exclude" users of older GD 
libraries and you think it's ok that these users are not 
able to use some PHP functions without segfaults then you 
can do some conditional compiling. In that way you can 
help users by saying "Update to GD 2.0.21 or better and 
recompile PHP OR use the bundled GD" instead of insisting 
only on the usage of the bundled one. 
 
But slowly the impression comes to me that you don't want 
users to use the external GD. You are already no longer 
giving support for the usage of the external one (At least 
nothing else then the silly "use the bundled GD library" 
response which does not respect the fact that the user may 
have reasons to use the external library). So maybe you 
should be consequential and remove compilation support for 
the external GD completely. Then you have no longer to 
deal with bug reports like this...
 [2004-07-26 16:15 UTC] adconrad at debian dot org
I'm not entirely sure which planet you're from, but a double-free bug from incorrect usage of a library is not a "bogus" bug.

Distributions link to external libraries because symbol clashes in shared application space is BAD (and your internal library doesn't use versioned symbols) and because security updates to a dozen statically compiled packages is much more of a pain in the ass than security updates to an individual library.

If you don't want distributions to package your stuff, get a consensus from your contributors and slap a more restructive license on it.  If you do want it being used widely, get rid of your NIH attitude and realise that YOU bundled libgd, they didn't "steal" it from you and "break" it.  It's your bundled version that you broke to work around a bug in PHP, rather than fixing the PHP bug.  That's not sane.
 [2004-07-26 16:25 UTC] k at ailis dot de
Haven't noticed that it was set to bogus again. So back to 
Open you go.
 [2004-07-27 02:27 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 11:01:30 2024 UTC