com php-src: Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop()): NEWS ext/gd/gd.c ext/gd/tests/bug66356.phpt main/php_version .h

From: Date: Fri, 27 Dec 2013 06:04:59 +0000
Subject: com php-src: Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop()): NEWS ext/gd/gd.c ext/gd/tests/bug66356.phpt main/php_version .h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-75475@lists.php.net to get a copy of this message
Commit: 2938329ce19cb8c4197dec146c3ec887c6f61d01 Author: Xinchen Hui <laruence@php.net> Fri, 27 Dec 2013 14:04:59 +0800 Parents: 6414fe283e3931d87416a155f4cfbaaf5ffca1ad Branches: PHP-5.5 PHP-5.6 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=2938329ce19cb8c4197dec146c3ec887c6f61d01 Log: Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop()) And also fixed the bug: arguments are altered after some calls Bugs: https://bugs.php.net/66356 Changed paths: M NEWS M ext/gd/gd.c A ext/gd/tests/bug66356.phpt M main/php_version.h

diff --git a/NEWS b/NEWS index eecd4e8..86eeb7c 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,7 @@ PHP NEWS . Fixed bug #66229 (128.0.0.0/16 isn't reserved any longer). (Adam) - GD: + . Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop()). (Laruence) . Fixed bug #64405 (Use freetype-config for determining freetype2 dir(s)). (Adam) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index fb25821..49970c1 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -1538,9 +1538,15 @@ PHP_FUNCTION(imagesetstyle) break; } - convert_to_long_ex(item); - - stylearr[index++] = Z_LVAL_PP(item); + if (Z_TYPE_PP(item) != IS_LONG) { + zval lval; + lval = **item; + zval_copy_ctor(&lval); + convert_to_long(&lval); + stylearr[index++] = Z_LVAL(lval); + } else { + stylearr[index++] = Z_LVAL_PP(item); + } } gdImageSetStyle(im, stylearr, index); @@ -3346,14 +3352,26 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled) for (i = 0; i < npoints; i++) { if (zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2), (void **) &var) == SUCCESS) { - SEPARATE_ZVAL((var)); - convert_to_long(*var); - points[i].x = Z_LVAL_PP(var); + if (Z_TYPE_PP(var) != IS_LONG) { + zval lval; + lval = **var; + zval_copy_ctor(&lval); + convert_to_long(&lval); + points[i].x = Z_LVAL(lval); + } else { + points[i].x = Z_LVAL_PP(var); + } } if (zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2) + 1, (void **) &var) == SUCCESS) { - SEPARATE_ZVAL(var); - convert_to_long(*var); - points[i].y = Z_LVAL_PP(var); + if (Z_TYPE_PP(var) != IS_LONG) { + zval lval; + lval = **var; + zval_copy_ctor(&lval); + convert_to_long(&lval); + points[i].y = Z_LVAL(lval); + } else { + points[i].y = Z_LVAL_PP(var); + } } } @@ -4859,9 +4877,15 @@ PHP_FUNCTION(imageconvolution) for (j=0; j<3; j++) { if (zend_hash_index_find(Z_ARRVAL_PP(var), (j), (void **) &var2) == SUCCESS) { - SEPARATE_ZVAL(var2); - convert_to_double(*var2); - matrix[i][j] = (float)Z_DVAL_PP(var2); + if (Z_TYPE_PP(var2) != IS_DOUBLE) { + zval dval; + dval = **var; + zval_copy_ctor(&dval); + convert_to_double(&dval); + matrix[i][j] = (float)Z_DVAL(dval); + } else { + matrix[i][j] = (float)Z_DVAL_PP(var2); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have a 3x3 matrix"); RETURN_FALSE; @@ -4954,28 +4978,60 @@ PHP_FUNCTION(imagecrop) ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd); if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) { - rect.x = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.x = Z_LVAL(lval); + } else { + rect.x = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) { - rect.y = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.y = Z_LVAL(lval); + } else { + rect.y = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) { - rect.width = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.width = Z_LVAL(lval); + } else { + rect.width = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) { - rect.height = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.height = Z_LVAL(lval); + } else { + rect.height = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height"); RETURN_FALSE; @@ -5124,8 +5180,13 @@ PHP_FUNCTION(imageaffine) affine[i] = Z_DVAL_PP(zval_affine_elem); break; case IS_STRING: - convert_to_double_ex(zval_affine_elem); - affine[i] = Z_DVAL_PP(zval_affine_elem); + { + zval dval; + dval = **zval_affine_elem; + zval_copy_ctor(&dval); + convert_to_double(&dval); + affine[i] = Z_DVAL(dval); + } break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i); @@ -5136,32 +5197,60 @@ PHP_FUNCTION(imageaffine) if (z_rect != NULL) { if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) { - convert_to_long_ex(tmp); - rect.x = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.x = Z_LVAL(lval); + } else { + rect.x = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) { - convert_to_long_ex(tmp); - rect.y = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.y = Z_LVAL(lval); + } else { + rect.y = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) { - convert_to_long_ex(tmp); - rect.width = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.width = Z_LVAL(lval); + } else { + rect.width = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) { - convert_to_long_ex(tmp); - rect.height = Z_LVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_LONG) { + zval lval; + lval = **tmp; + zval_copy_ctor(&lval); + convert_to_long(&lval); + rect.height = Z_LVAL(lval); + } else { + rect.height = Z_LVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height"); RETURN_FALSE; @@ -5211,16 +5300,30 @@ PHP_FUNCTION(imageaffinematrixget) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array expected as options"); } if (zend_hash_find(HASH_OF(options), "x", sizeof("x"), (void **)&tmp) != FAILURE) { - convert_to_double_ex(tmp); - x = Z_DVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_DOUBLE) { + zval dval; + dval = **tmp; + zval_copy_ctor(&dval); + convert_to_double(&dval); + x = Z_DVAL(dval); + } else { + x = Z_DVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position"); RETURN_FALSE; } if (zend_hash_find(HASH_OF(options), "y", sizeof("y"), (void **)&tmp) != FAILURE) { - convert_to_double_ex(tmp); - y = Z_DVAL_PP(tmp); + if (Z_TYPE_PP(tmp) != IS_DOUBLE) { + zval dval; + dval = **tmp; + zval_copy_ctor(&dval); + convert_to_double(&dval); + y = Z_DVAL(dval); + } else { + y = Z_DVAL_PP(tmp); + } } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position"); RETURN_FALSE; @@ -5300,8 +5403,13 @@ PHP_FUNCTION(imageaffinematrixconcat) m1[i] = Z_DVAL_PP(tmp); break; case IS_STRING: - convert_to_double_ex(tmp); - m1[i] = Z_DVAL_PP(tmp); + { + zval dval; + dval = **tmp; + zval_copy_ctor(&dval); + convert_to_double(&dval); + m1[i] = Z_DVAL(dval); + } break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i); @@ -5317,8 +5425,13 @@ PHP_FUNCTION(imageaffinematrixconcat) m2[i] = Z_DVAL_PP(tmp); break; case IS_STRING: - convert_to_double_ex(tmp); - m2[i] = Z_DVAL_PP(tmp); + { + zval dval; + dval = **tmp; + zval_copy_ctor(&dval); + convert_to_double(&dval); + m2[i] = Z_DVAL(dval); + } break; default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i); diff --git a/ext/gd/tests/bug66356.phpt b/ext/gd/tests/bug66356.phpt new file mode 100644 index 0000000..f881494 --- /dev/null +++ b/ext/gd/tests/bug66356.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #66356 (Heap Overflow Vulnerability in imagecrop()) +--SKIPIF-- +<?php + if(!extension_loaded('gd')){ die('skip gd extension not available'); } +?> +--FILE-- +<?php +$img = imagecreatetruecolor(10, 10); +$img = imagecrop($img, array("x" => "a", "y" => 0, "width" => 10, "height" => 10)); +$arr = array("x" => "a", "y" => "12b", "width" => 10, "height" => 10); +$img = imagecrop($img, $arr); +print_r($arr); +?> +--EXPECTF-- +Array +( + [x] => a + [y] => 12b + [width] => 10 + [height] => 10 +) diff --git a/main/php_version.h b/main/php_version.h index 8d30a36..d9ea4aa 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 #define PHP_MINOR_VERSION 5 -#define PHP_RELEASE_VERSION 8 +#define PHP_RELEASE_VERSION 5 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.5.8-dev" -#define PHP_VERSION_ID 50508 +#define PHP_VERSION "5.5.5-dev" +#define PHP_VERSION_ID 50505
« previous php.cvs (#75475) next »