Potential infinite loop in gdImageCreateFromGifCtx
| 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 | ||
[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 commits
[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
[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
-Status: Analyzed +Status: Closed
[2018-01-16 09:05 UTC] kaplan@php.net
-CVE-ID: needed +CVE-ID: 2018-5711