php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68713 infinite loop / infinite free
Submitted: 2015-01-02 07:37 UTC Modified: 2015-01-03 05:23 UTC
From: bugreports at internot dot info Assigned: remi (profile)
Status: Closed Package: GD related
PHP Version: master-Git-2015-01-02 (Git) OS: Linux Ubuntu 14.04
Private report: No CVE-ID: None
 [2015-01-02 07:37 UTC] bugreports at internot dot info
Description:
------------
Hi,

In /ext/gd/libgd/gd.c:


3072                for (yy = y; yy >= yy - 1; y--) {
3073                        gdFree(src->tpixels[y]);
3074                }

If this is ever run, it will be stuck in a loop, which will eventually cause invalid frees (and/or) double frees.

I'm guessing it's supposed to be like this code:

3053        for (yy = y - 1; yy >= yy - 1; yy--) {
3054                gdFree(src->pixels[yy]);
3055        }

"for (yy = y - 1;"



Thanks,


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-01-02 08:13 UTC] remi@php.net
-Assigned To: +Assigned To: remi
 [2015-01-02 08:13 UTC] remi@php.net
This have to be fixed in libgd first

Notice: I don't think this is really a security bug

Please check https://bitbucket.org/libgd/gd-libgd/commits/3c0d2203b2672b688d4d2326ff3a60b019879062
 [2015-01-02 08:21 UTC] bugreports at internot dot info
Hi,

Why do you think this is not a sec. issue?
I think(but am not 100% sure) that it will cause the loop to go down the 0, then it'll go to -1(aka. max int), and will try to free invalid places.

e.g:

unsigned int y = 5;
unsigned int yy;
                for (yy = y; yy >= yy - 1; y--) {
			printf("%u\n", y);
                }

outputs:

$ ./a.out | head -n10
5
4
3
2
1
0
4294967295
4294967294
4294967293




1. it will go on forever, and 2. it will try to free invalid memory.


Thanks,
 [2015-01-02 08:29 UTC] remi@php.net
In PHP gdMalloc is mapped to emalloc which will never return NULL (but bailout with memory limit error), so the "clean_on_error" will never be used.

And I haven't say there is no bug, yes the infinite loop exists in libgd (not in PHP), I just say I can't see how this can raise security issue.
 [2015-01-02 08:38 UTC] bugreports at internot dot info
So you're saying that clean_on_error can never be called, so it can't get to that code? Why is it there then?

Anyways, if clean_on_error was reached and it did get to that code, it will cause either a denial of service, or a crash(or both). the crash may be exploitable due to it calling invalid memory. Perhaps somebody that knows more about the security of PHP(aka. not me) should comment.

Thanks,
 [2015-01-03 05:11 UTC] stas@php.net
Why the condition is "yy >= yy - 1"? I imagine for unsigned it's the same as yy != 0 but why not write it this way then? 

In any case, emalloc in PHP never returns NULL so in PHP context it is kind of an academic exercise.
 [2015-01-03 05:15 UTC] stas@php.net
-Status: Assigned +Status: Open -Type: Security +Type: Bug
 [2015-01-03 05:15 UTC] stas@php.net
We may want to merge the upstream for cleanness but doesn't look like security issue in PHP.
 [2015-01-03 05:23 UTC] bugreports at internot dot info
Ok cool.

@remi: Do you know of any programs using libgd, where gdMalloc does not call an emalloc-"like" allocator, that just quits on failure?



Thanks,
 [2015-01-03 07:36 UTC] remi@php.net
Automatic comment on behalf of remi
Revision: http://git.php.net/?p=php-src.git;a=commit;h=df4aaa81ef5a65056e09958a5ab62fa8d296bfc1
Log: Fix Bug #68713  infinite loop / infinite free
 [2015-01-03 07:36 UTC] remi@php.net
-Status: Assigned +Status: Closed
 [2016-07-20 11:40 UTC] davey@php.net
Automatic comment on behalf of remi
Revision: http://git.php.net/?p=php-src.git;a=commit;h=df4aaa81ef5a65056e09958a5ab62fa8d296bfc1
Log: Fix Bug #68713  infinite loop / infinite free
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 14:01:30 2024 UTC