Skip to content

Commit 2938329

Browse files
committed
Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop())
And also fixed the bug: arguments are altered after some calls
1 parent 6414fe2 commit 2938329

File tree

4 files changed

+173
-37
lines changed

4 files changed

+173
-37
lines changed

Diff for: NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ PHP NEWS
2929
. Fixed bug #66229 (128.0.0.0/16 isn't reserved any longer). (Adam)
3030

3131
- GD:
32+
. Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop()). (Laruence)
3233
. Fixed bug #64405 (Use freetype-config for determining freetype2 dir(s)).
3334
(Adam)
3435

Diff for: ext/gd/gd.c

+147-34
Original file line numberDiff line numberDiff line change
@@ -1538,9 +1538,15 @@ PHP_FUNCTION(imagesetstyle)
15381538
break;
15391539
}
15401540

1541-
convert_to_long_ex(item);
1542-
1543-
stylearr[index++] = Z_LVAL_PP(item);
1541+
if (Z_TYPE_PP(item) != IS_LONG) {
1542+
zval lval;
1543+
lval = **item;
1544+
zval_copy_ctor(&lval);
1545+
convert_to_long(&lval);
1546+
stylearr[index++] = Z_LVAL(lval);
1547+
} else {
1548+
stylearr[index++] = Z_LVAL_PP(item);
1549+
}
15441550
}
15451551

15461552
gdImageSetStyle(im, stylearr, index);
@@ -3346,14 +3352,26 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)
33463352

33473353
for (i = 0; i < npoints; i++) {
33483354
if (zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2), (void **) &var) == SUCCESS) {
3349-
SEPARATE_ZVAL((var));
3350-
convert_to_long(*var);
3351-
points[i].x = Z_LVAL_PP(var);
3355+
if (Z_TYPE_PP(var) != IS_LONG) {
3356+
zval lval;
3357+
lval = **var;
3358+
zval_copy_ctor(&lval);
3359+
convert_to_long(&lval);
3360+
points[i].x = Z_LVAL(lval);
3361+
} else {
3362+
points[i].x = Z_LVAL_PP(var);
3363+
}
33523364
}
33533365
if (zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2) + 1, (void **) &var) == SUCCESS) {
3354-
SEPARATE_ZVAL(var);
3355-
convert_to_long(*var);
3356-
points[i].y = Z_LVAL_PP(var);
3366+
if (Z_TYPE_PP(var) != IS_LONG) {
3367+
zval lval;
3368+
lval = **var;
3369+
zval_copy_ctor(&lval);
3370+
convert_to_long(&lval);
3371+
points[i].y = Z_LVAL(lval);
3372+
} else {
3373+
points[i].y = Z_LVAL_PP(var);
3374+
}
33573375
}
33583376
}
33593377

@@ -4859,9 +4877,15 @@ PHP_FUNCTION(imageconvolution)
48594877

48604878
for (j=0; j<3; j++) {
48614879
if (zend_hash_index_find(Z_ARRVAL_PP(var), (j), (void **) &var2) == SUCCESS) {
4862-
SEPARATE_ZVAL(var2);
4863-
convert_to_double(*var2);
4864-
matrix[i][j] = (float)Z_DVAL_PP(var2);
4880+
if (Z_TYPE_PP(var2) != IS_DOUBLE) {
4881+
zval dval;
4882+
dval = **var;
4883+
zval_copy_ctor(&dval);
4884+
convert_to_double(&dval);
4885+
matrix[i][j] = (float)Z_DVAL(dval);
4886+
} else {
4887+
matrix[i][j] = (float)Z_DVAL_PP(var2);
4888+
}
48654889
} else {
48664890
php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have a 3x3 matrix");
48674891
RETURN_FALSE;
@@ -4954,28 +4978,60 @@ PHP_FUNCTION(imagecrop)
49544978
ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
49554979

49564980
if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
4957-
rect.x = Z_LVAL_PP(tmp);
4981+
if (Z_TYPE_PP(tmp) != IS_LONG) {
4982+
zval lval;
4983+
lval = **tmp;
4984+
zval_copy_ctor(&lval);
4985+
convert_to_long(&lval);
4986+
rect.x = Z_LVAL(lval);
4987+
} else {
4988+
rect.x = Z_LVAL_PP(tmp);
4989+
}
49584990
} else {
49594991
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
49604992
RETURN_FALSE;
49614993
}
49624994

49634995
if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) {
4964-
rect.y = Z_LVAL_PP(tmp);
4996+
if (Z_TYPE_PP(tmp) != IS_LONG) {
4997+
zval lval;
4998+
lval = **tmp;
4999+
zval_copy_ctor(&lval);
5000+
convert_to_long(&lval);
5001+
rect.y = Z_LVAL(lval);
5002+
} else {
5003+
rect.y = Z_LVAL_PP(tmp);
5004+
}
49655005
} else {
49665006
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
49675007
RETURN_FALSE;
49685008
}
49695009

49705010
if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) {
4971-
rect.width = Z_LVAL_PP(tmp);
5011+
if (Z_TYPE_PP(tmp) != IS_LONG) {
5012+
zval lval;
5013+
lval = **tmp;
5014+
zval_copy_ctor(&lval);
5015+
convert_to_long(&lval);
5016+
rect.width = Z_LVAL(lval);
5017+
} else {
5018+
rect.width = Z_LVAL_PP(tmp);
5019+
}
49725020
} else {
49735021
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width");
49745022
RETURN_FALSE;
49755023
}
49765024

49775025
if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) {
4978-
rect.height = Z_LVAL_PP(tmp);
5026+
if (Z_TYPE_PP(tmp) != IS_LONG) {
5027+
zval lval;
5028+
lval = **tmp;
5029+
zval_copy_ctor(&lval);
5030+
convert_to_long(&lval);
5031+
rect.height = Z_LVAL(lval);
5032+
} else {
5033+
rect.height = Z_LVAL_PP(tmp);
5034+
}
49795035
} else {
49805036
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height");
49815037
RETURN_FALSE;
@@ -5124,8 +5180,13 @@ PHP_FUNCTION(imageaffine)
51245180
affine[i] = Z_DVAL_PP(zval_affine_elem);
51255181
break;
51265182
case IS_STRING:
5127-
convert_to_double_ex(zval_affine_elem);
5128-
affine[i] = Z_DVAL_PP(zval_affine_elem);
5183+
{
5184+
zval dval;
5185+
dval = **zval_affine_elem;
5186+
zval_copy_ctor(&dval);
5187+
convert_to_double(&dval);
5188+
affine[i] = Z_DVAL(dval);
5189+
}
51295190
break;
51305191
default:
51315192
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i);
@@ -5136,32 +5197,60 @@ PHP_FUNCTION(imageaffine)
51365197

51375198
if (z_rect != NULL) {
51385199
if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
5139-
convert_to_long_ex(tmp);
5140-
rect.x = Z_LVAL_PP(tmp);
5200+
if (Z_TYPE_PP(tmp) != IS_LONG) {
5201+
zval lval;
5202+
lval = **tmp;
5203+
zval_copy_ctor(&lval);
5204+
convert_to_long(&lval);
5205+
rect.x = Z_LVAL(lval);
5206+
} else {
5207+
rect.x = Z_LVAL_PP(tmp);
5208+
}
51415209
} else {
51425210
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
51435211
RETURN_FALSE;
51445212
}
51455213

51465214
if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) {
5147-
convert_to_long_ex(tmp);
5148-
rect.y = Z_LVAL_PP(tmp);
5215+
if (Z_TYPE_PP(tmp) != IS_LONG) {
5216+
zval lval;
5217+
lval = **tmp;
5218+
zval_copy_ctor(&lval);
5219+
convert_to_long(&lval);
5220+
rect.y = Z_LVAL(lval);
5221+
} else {
5222+
rect.y = Z_LVAL_PP(tmp);
5223+
}
51495224
} else {
51505225
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
51515226
RETURN_FALSE;
51525227
}
51535228

51545229
if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) {
5155-
convert_to_long_ex(tmp);
5156-
rect.width = Z_LVAL_PP(tmp);
5230+
if (Z_TYPE_PP(tmp) != IS_LONG) {
5231+
zval lval;
5232+
lval = **tmp;
5233+
zval_copy_ctor(&lval);
5234+
convert_to_long(&lval);
5235+
rect.width = Z_LVAL(lval);
5236+
} else {
5237+
rect.width = Z_LVAL_PP(tmp);
5238+
}
51575239
} else {
51585240
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width");
51595241
RETURN_FALSE;
51605242
}
51615243

51625244
if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) {
5163-
convert_to_long_ex(tmp);
5164-
rect.height = Z_LVAL_PP(tmp);
5245+
if (Z_TYPE_PP(tmp) != IS_LONG) {
5246+
zval lval;
5247+
lval = **tmp;
5248+
zval_copy_ctor(&lval);
5249+
convert_to_long(&lval);
5250+
rect.height = Z_LVAL(lval);
5251+
} else {
5252+
rect.height = Z_LVAL_PP(tmp);
5253+
}
51655254
} else {
51665255
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height");
51675256
RETURN_FALSE;
@@ -5211,16 +5300,30 @@ PHP_FUNCTION(imageaffinematrixget)
52115300
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array expected as options");
52125301
}
52135302
if (zend_hash_find(HASH_OF(options), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
5214-
convert_to_double_ex(tmp);
5215-
x = Z_DVAL_PP(tmp);
5303+
if (Z_TYPE_PP(tmp) != IS_DOUBLE) {
5304+
zval dval;
5305+
dval = **tmp;
5306+
zval_copy_ctor(&dval);
5307+
convert_to_double(&dval);
5308+
x = Z_DVAL(dval);
5309+
} else {
5310+
x = Z_DVAL_PP(tmp);
5311+
}
52165312
} else {
52175313
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
52185314
RETURN_FALSE;
52195315
}
52205316

52215317
if (zend_hash_find(HASH_OF(options), "y", sizeof("y"), (void **)&tmp) != FAILURE) {
5222-
convert_to_double_ex(tmp);
5223-
y = Z_DVAL_PP(tmp);
5318+
if (Z_TYPE_PP(tmp) != IS_DOUBLE) {
5319+
zval dval;
5320+
dval = **tmp;
5321+
zval_copy_ctor(&dval);
5322+
convert_to_double(&dval);
5323+
y = Z_DVAL(dval);
5324+
} else {
5325+
y = Z_DVAL_PP(tmp);
5326+
}
52245327
} else {
52255328
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
52265329
RETURN_FALSE;
@@ -5300,8 +5403,13 @@ PHP_FUNCTION(imageaffinematrixconcat)
53005403
m1[i] = Z_DVAL_PP(tmp);
53015404
break;
53025405
case IS_STRING:
5303-
convert_to_double_ex(tmp);
5304-
m1[i] = Z_DVAL_PP(tmp);
5406+
{
5407+
zval dval;
5408+
dval = **tmp;
5409+
zval_copy_ctor(&dval);
5410+
convert_to_double(&dval);
5411+
m1[i] = Z_DVAL(dval);
5412+
}
53055413
break;
53065414
default:
53075415
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i);
@@ -5317,8 +5425,13 @@ PHP_FUNCTION(imageaffinematrixconcat)
53175425
m2[i] = Z_DVAL_PP(tmp);
53185426
break;
53195427
case IS_STRING:
5320-
convert_to_double_ex(tmp);
5321-
m2[i] = Z_DVAL_PP(tmp);
5428+
{
5429+
zval dval;
5430+
dval = **tmp;
5431+
zval_copy_ctor(&dval);
5432+
convert_to_double(&dval);
5433+
m2[i] = Z_DVAL(dval);
5434+
}
53225435
break;
53235436
default:
53245437
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i);

Diff for: ext/gd/tests/bug66356.phpt

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
Bug #66356 (Heap Overflow Vulnerability in imagecrop())
3+
--SKIPIF--
4+
<?php
5+
if(!extension_loaded('gd')){ die('skip gd extension not available'); }
6+
?>
7+
--FILE--
8+
<?php
9+
$img = imagecreatetruecolor(10, 10);
10+
$img = imagecrop($img, array("x" => "a", "y" => 0, "width" => 10, "height" => 10));
11+
$arr = array("x" => "a", "y" => "12b", "width" => 10, "height" => 10);
12+
$img = imagecrop($img, $arr);
13+
print_r($arr);
14+
?>
15+
--EXPECTF--
16+
Array
17+
(
18+
[x] => a
19+
[y] => 12b
20+
[width] => 10
21+
[height] => 10
22+
)

Diff for: main/php_version.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/* edit configure.in to change version number */
33
#define PHP_MAJOR_VERSION 5
44
#define PHP_MINOR_VERSION 5
5-
#define PHP_RELEASE_VERSION 8
5+
#define PHP_RELEASE_VERSION 5
66
#define PHP_EXTRA_VERSION "-dev"
7-
#define PHP_VERSION "5.5.8-dev"
8-
#define PHP_VERSION_ID 50508
7+
#define PHP_VERSION "5.5.5-dev"
8+
#define PHP_VERSION_ID 50505

0 commit comments

Comments
 (0)