php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #75571 Potential infinite loop in gdImageCreateFromGifCtx
Submitted: 2017-11-25 16:53 UTC Modified: 2018-01-16 09:05 UTC
From: orange at chroot dot org Assigned: stas (profile)
Status: Closed Package: GD related
PHP Version: 5.6.32 OS: Ubuntu 17.10
Private report: No CVE-ID: 2018-5711
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: orange at chroot dot org
New email:
PHP Version: OS:

 

 [2017-11-25 16:53 UTC] orange at chroot dot org
Description:
------------
Hi, I found an infinity loop in GD GIF core parsing function. 

It is easy to trigger in web application if the web use GD as its image library. For example, It can be triggered by the following functions

* imagecreatefromgif
* imagecreatefromstring

This vulnerability will lead to a Denied of Service and exhausted the server resource.



There is a do-while in file `ext/gd/libgd/gd_gif_in.c` and function `LWZReadByte_`
```
do {
    sd->firstcode = sd->oldcode =
    GetCode(fd, &sd->scd, sd->code_size, FALSE, ZeroDataBlockP);
} while (sd->firstcode == sd->clear_code);
```
https://github.com/php/php-src/blob/c5767db441e4db2a1e07b5880129ad7ce0b25b6f/ext/gd/libgd/gd_gif_in.c#L460


The implementation of `GetCode` is in `GetCode_`
```
static int
GetCode_(gdIOCtx *fd, CODE_STATIC_DATA *scd, int code_size, int flag, int *ZeroDataBlockP)
{
    int           i, j, ret;
    unsigned char count;

    ... 

    if ((count = GetDataBlock(fd, &scd->buf[2], ZeroDataBlockP)) <= 0)
        scd->done = TRUE;

    ...
}
```
https://github.com/php/php-src/blob/c5767db441e4db2a1e07b5880129ad7ce0b25b6f/ext/gd/libgd/gd_gif_in.c#L376

As you can see, `GetDataBlock` will read the image data and return the length. If EOF, returned -1. But the variable `count` is `unsigned char`, will always be positive value. So the line `scd->done = TRUE` will never be executed.


I think the easiest patch is change `unsigned char` to `int`.



Test script:
---------------
$ curl https://gist.githubusercontent.com/orangetw/adb0e2519df267eb54d8b68027a91d4c/raw/7a7d6938f59dd89e9a9b7304d71f8f6640609479/poc.gif.xxd | xxd -r > poc.gif

$ php -r 'imagecreatefromgif("poc.gif");'
hang here...



Patches

fix-75571 (last revision 2017-11-29 18:54 UTC by cmb@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-11-28 17:19 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 [2017-11-29 18:53 UTC] cmb@php.net
-Summary: Infinity loop in GD GIF parsing function leads to Denied of Service +Summary: Potential infinite loop in gdImageCreateFromGifCtx -Status: Assigned +Status: Analyzed -Assigned To: cmb +Assigned To: stas
 [2017-11-29 18:53 UTC] cmb@php.net
Thanks for reporting this issue!  Indeed, this is an exploitable
Denial of Service vulnerability, and all PHP versions are
affected.  Furthermore, libgd is also affected; I have already
forwarded this issue to security@libgd.org including a respective
patch.

Stas, can you please commit the patch I'm going to attach to the
security repo (PHP-5.6 and up)?  It would be nice if it were
possible to sync the respective releases of GD and PHP.
 [2017-11-29 18:54 UTC] cmb@php.net
The following patch has been added/updated:

Patch Name: fix-75571
Revision:   1511981663
URL:        https://bugs.php.net/patch-display.php?bug=75571&patch=fix-75571&revision=1511981663
 [2017-12-01 22:02 UTC] stas@php.net
The fix is in security repo as 07dd4c36e5b2bd6032a1e589f31e87ccde4334c1 and in https://gist.github.com/2c5331292f9e77e694ad9dd8901a3a11
 [2017-12-01 22:03 UTC] stas@php.net
-CVE-ID: +CVE-ID: needed
 [2018-01-02 04:27 UTC] stas@php.net
-PHP Version: 7.2Git-2017-11-25 (Git) +PHP Version: 5.6.32
 [2018-01-02 04:27 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8d6e9588671136837533fe3785657c31c5b52767
Log: Fixed bug #75571: Potential infinite loop in gdImageCreateFromGifCtx
 [2018-01-02 04:27 UTC] stas@php.net
-Status: Analyzed +Status: Closed
 [2018-01-02 05:25 UTC] stas@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=8d6e9588671136837533fe3785657c31c5b52767
Log: Fixed bug #75571: Potential infinite loop in gdImageCreateFromGifCtx
 [2018-01-02 06:32 UTC] ab@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=40d4118efe85b967b5ca2606f9d3009e013faf36
Log: Fixed bug #75571: Potential infinite loop in gdImageCreateFromGifCtx
 [2018-01-02 22:06 UTC] pollita@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=3b50e238b2d7ec2a3d46aa428694e02479477b7a
Log: Fixed bug #75571: Potential infinite loop in gdImageCreateFromGifCtx
 [2018-01-03 02:03 UTC] pollita@php.net
Automatic comment on behalf of cmbecker69@gmx.de
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f03943129b18fac7bbb0801eef8298e13cfce106
Log: Fixed bug #75571: Potential infinite loop in gdImageCreateFromGifCtx
 [2018-01-16 09:05 UTC] kaplan@php.net
-CVE-ID: needed +CVE-ID: 2018-5711
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Dec 11 22:01:27 2024 UTC