Sec Bug->Bug #72350 [Opn]: gdImageFillToBorder stack-overflow when invalid color is used

From: Date: Tue, 07 Jun 2016 04:51:35 +0000
Subject: Sec Bug->Bug #72350 [Opn]: gdImageFillToBorder stack-overflow when invalid color is used
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-201497@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=72350&edit=1 ID: 72350 Updated by: pajoye@php.net Reported by: fernando at null-life dot com Summary: gdImageFillToBorder stack-overflow when invalid color is used Status: Open -Type: Security +Type: Bug Package: GD related Operating System: * PHP Version: 7.0.7 Block user comment: N Private report: Y New Comment: Also not a security issue. See https://github.com/libgd/libgd/issues/215 Sync coming for next php releases. Previous Comments: ------------------------------------------------------------------------ [2016-06-07 04:48:05] pajoye@php.net @Stas it is done the same way. Gd is bundled with some php specific behaviors so it is all good. Most contributOrson in Gd are in the core as well. Only thing we do is to be sure to release sec fixes at the same time. ------------------------------------------------------------------------ [2016-06-06 20:53:46] stas@php.net Seems to be libgd issue, please report upstream. ------------------------------------------------------------------------ [2016-06-06 19:58:31] fernando at null-life dot com Description: ------------ Invalid color causes stack exhaustion by recursive call to function gdImageFillToBorder when the image used is not truecolor. Source code: https://github.com/php/php-src/blob/master/ext/gd/libgd/gd.c#L1811 if (y > 0) { lastBorder = 1; for (i = leftLimit; i <= rightLimit; i++) { int c = gdImageGetPixel(im, i, y - 1); if (lastBorder) { if ((c != border) && (c != color)) { gdImageFillToBorder(im, i, y - 1, border, color); lastBorder = 0; } } else if ((c == border) || (c == color)) { lastBorder = 1; } } } /* Below */ if (y < ((im->sy) - 1)) { lastBorder = 1; for (i = leftLimit; i <= rightLimit; i++) { int c = gdImageGetPixel(im, i, y + 1); if (lastBorder) { if ((c != border) && (c != color)) { gdImageFillToBorder(im, i, y + 1, border, color); lastBorder = 0; } } else if ((c == border) || (c == color)) { lastBorder = 1; } } } im->alphaBlendingFlag = restoreAlphaBlending; gdb -q --args /home/user/php-7.0/sapi/cli/php -n poc.php Reading symbols from /home/user/php-7.0/sapi/cli/php...done. (gdb) b gd.c:1811 Breakpoint 1 at 0x8176146: file /home/user/php-7.0/ext/gd/libgd/gd.c, line 1811. (gdb) b gd.c:1829 Breakpoint 2 at 0x81761f2: file /home/user/php-7.0/ext/gd/libgd/gd.c, line 1829. (gdb) r Starting program: /home/user/php-7.0/sapi/cli/php -n poc.php Breakpoint 2, php_gd_gdImageFillToBorder (im=0xf5a6c000, x=0, y=0, border=1, color=313) at /home/user/php-7.0/ext/gd/libgd/gd.c:1829 1829 gdImageFillToBorder(im, i, y + 1, border, color); (gdb) p c $1 = 0 (gdb) c Continuing. Breakpoint 1, php_gd_gdImageFillToBorder (im=0xf5a6c000, x=0, y=1, border=1, color=313) at /home/user/php-7.0/ext/gd/libgd/gd.c:1811 1811 if ((c != border) && (c != color)) { (gdb) p c $2 = 57 (different of color 313) (gdb) c Continuing. Breakpoint 2, php_gd_gdImageFillToBorder (im=0xf5a6c000, x=0, y=0, border=1, color=313) at /home/user/php-7.0/ext/gd/libgd/gd.c:1829 1829 gdImageFillToBorder(im, i, y + 1, border, color); (gdb) p c $3 = 57 (different of color 313) (gdb) c Continuing. Breakpoint 1, php_gd_gdImageFillToBorder (im=0xf5a6c000, x=0, y=1, border=1, color=313) at /home/user/php-7.0/ext/gd/libgd/gd.c:1811 1811 if ((c != border) && (c != color)) { (gdb) p c $4 = 57 (different of color 313) This was fixed on libgd upstream: https://github.com/libgd/libgd/commit/77f619d48259383628c3ec4654b1ad578e9eb40e Test script: --------------- <?php $img = imagecreate(10, 10); imagefilltoborder($img, 0, 0, 1, 0x139); Expected result: ---------------- No crash Actual result: -------------- user@Xenial32-2:~/crashes/fillborder$ /ramdisk/php-71/sapi/cli/php -n poc.php ASAN:SIGSEGV ================================================================= ==5027==ERROR: AddressSanitizer: stack-overflow on address 0xff276ff0 (pc 0x085ee3f8 bp 0x1e4cdb90 sp 0xff276ff0 T0) #0 0x85ee3f7 in php_gd_gdImageSetPixel /home/user/php-7.1asan/ext/gd/libgd/gd.c:755 #1 0xf266bfff (<unknown module>) SUMMARY: AddressSanitizer: stack-overflow /home/user/php-7.1asan/ext/gd/libgd/gd.c:755 php_gd_gdImageSetPixel ==5027==ABORTING user@Xenial32-2:~/crashes/fillborder$ /ramdisk/php-71/sapi/cli/php -n poc.php ASAN:SIGSEGV ================================================================= ==5771==ERROR: AddressSanitizer: stack-overflow on address 0xff758ff4 (pc 0x085ebfcf bp 0xfffffffc sp 0xff758ff0 T0) #0 0x85ebfce in gdImageTileApply /home/user/php-7.1asan/ext/gd/libgd/gd.c:869 #1 0x85ebfce in php_gd_gdImageSetPixel /home/user/php-7.1asan/ext/gd/libgd/gd.c:749 #2 0x85f7eae in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1788 #3 0x85f8f32 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1829 #4 0x85f8e04 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1812 #5 0x85f8f32 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1829 #6 0x85f8e04 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1812 #7 0x85f8f32 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1829 #8 0x85f8e04 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1812 #9 0x85f8f32 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1829 #10 0x85f8e04 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1812 #11 0x85f8f32 in php_gd_gdImageFillToBorder /home/user/php-7.1asan/ext/gd/libgd/gd.c:1829 ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=72350&edit=1

« previous php.bugs (#201497) next »