]> granicus.if.org Git - php/commitdiff
Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop())
authorXinchen Hui <laruence@php.net>
Fri, 27 Dec 2013 06:04:59 +0000 (14:04 +0800)
committerXinchen Hui <laruence@php.net>
Fri, 27 Dec 2013 06:04:59 +0000 (14:04 +0800)
And also fixed the bug: arguments are altered after some calls

NEWS
ext/gd/gd.c
ext/gd/tests/bug66356.phpt [new file with mode: 0644]
main/php_version.h

diff --git a/NEWS b/NEWS
index eecd4e800284a7d0d3e6f0da0cbd1386655cae6e..86eeb7cea9fef34108eb023e82e5b38875db57e6 100644 (file)
--- 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)
     
index fb258214a153ffed7437af35543f6f506281c8cf..49970c168838a7c0882687d56e69089cac2857d9 100644 (file)
@@ -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 (file)
index 0000000..f881494
--- /dev/null
@@ -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
+)
index 8d30a367d368e44302b7f45f1445b4a8b3c57f34..d9ea4aab3cd61f5dbff50d8113875e70834728b3 100644 (file)
@@ -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