Skip to content

Commit

Permalink
Merge branch 'PHP-5.5' into PHP-5.6
Browse files Browse the repository at this point in the history
* PHP-5.5:
  Fix memory leak
  Fix bug #72099: xml_parse_into_struct segmentation fault
  5.5.36 now
  Fix bug #72094 - Out of bounds heap read access in exif header processing
  Fix bug #72093: bcpowmod accepts negative scale and corrupts _one_ definition
  Fix bug #72061 - Out-of-bounds reads in zif_grapheme_stripos with negative offset
  Fix for bug #71912 (libgd: signedness vulnerability)
  Typo in NEWS

Conflicts:
	configure.in
	main/php_version.h
  • Loading branch information
smalyshev committed Apr 27, 2016
2 parents 9f389cc + 61c7a06 commit e315a16
Show file tree
Hide file tree
Showing 15 changed files with 244 additions and 79 deletions.
60 changes: 41 additions & 19 deletions ext/bcmath/bcmath.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,21 @@ static void php_str2num(bc_num *num, char *str TSRMLS_DC)
}
/* }}} */

/* {{{ split_bc_num
Convert to bc_num detecting scale */
static bc_num split_bc_num(bc_num num) {
bc_num newnum;
if (num->n_refs >= 1) {
return num;
}
newnum = _bc_new_num_ex(0, 0, 0);
*newnum = *num;
newnum->n_refs = 1;
num->n_refs--;
return newnum;
}
/* }}} */

/* {{{ proto string bcadd(string left_operand, string right_operand [, int scale])
Returns the sum of two arbitrary precision numbers */
PHP_FUNCTION(bcadd)
Expand All @@ -214,7 +229,7 @@ PHP_FUNCTION(bcadd)
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
return;
}

if (argc == 3) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}
Expand All @@ -225,11 +240,12 @@ PHP_FUNCTION(bcadd)
php_str2num(&first, left TSRMLS_CC);
php_str2num(&second, right TSRMLS_CC);
bc_add (first, second, &result, scale);

if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}

Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
Expand All @@ -253,7 +269,7 @@ PHP_FUNCTION(bcsub)
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
return;
}

if (argc == 3) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}
Expand All @@ -266,6 +282,7 @@ PHP_FUNCTION(bcsub)
bc_sub (first, second, &result, scale);

if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}

Expand All @@ -292,11 +309,11 @@ PHP_FUNCTION(bcmul)
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
return;
}

if (argc == 3) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}

bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
Expand All @@ -305,6 +322,7 @@ PHP_FUNCTION(bcmul)
bc_multiply (first, second, &result, scale TSRMLS_CC);

if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}

Expand All @@ -331,11 +349,11 @@ PHP_FUNCTION(bcdiv)
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
return;
}

if (argc == 3) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}

bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
Expand All @@ -345,6 +363,7 @@ PHP_FUNCTION(bcdiv)
switch (bc_divide(first, second, &result, scale TSRMLS_CC)) {
case 0: /* OK */
if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}
Z_STRVAL_P(return_value) = bc_num2str(result);
Expand Down Expand Up @@ -374,13 +393,13 @@ PHP_FUNCTION(bcmod)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &left, &left_len, &right, &right_len) == FAILURE) {
return;
}

bc_init_num(&first TSRMLS_CC);
bc_init_num(&second TSRMLS_CC);
bc_init_num(&result TSRMLS_CC);
bc_str2num(&first, left, 0 TSRMLS_CC);
bc_str2num(&second, right, 0 TSRMLS_CC);

switch (bc_modulo(first, second, &result, 0 TSRMLS_CC)) {
case 0:
Z_STRVAL_P(return_value) = bc_num2str(result);
Expand All @@ -391,7 +410,7 @@ PHP_FUNCTION(bcmod)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Division by zero");
break;
}

bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&result);
Expand Down Expand Up @@ -424,16 +443,17 @@ PHP_FUNCTION(bcpowmod)
scale_int = (int) ((int)scale < 0) ? 0 : scale;

if (bc_raisemod(first, second, mod, &result, scale_int TSRMLS_CC) != -1) {
if (result->n_scale > scale) {
result->n_scale = scale;
if (result->n_scale > scale_int) {
result = split_bc_num(result);
result->n_scale = scale_int;
}
Z_STRVAL_P(return_value) = bc_num2str(result);
Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
Z_TYPE_P(return_value) = IS_STRING;
} else {
RETVAL_FALSE;
}

bc_free_num(&first);
bc_free_num(&second);
bc_free_num(&mod);
Expand All @@ -455,7 +475,7 @@ PHP_FUNCTION(bcpow)
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
return;
}

if (argc == 3) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}
Expand All @@ -468,6 +488,7 @@ PHP_FUNCTION(bcpow)
bc_raise (first, second, &result, scale TSRMLS_CC);

if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}

Expand All @@ -494,16 +515,17 @@ PHP_FUNCTION(bcsqrt)
if (zend_parse_parameters(argc TSRMLS_CC, "s|l", &left, &left_len, &scale_param) == FAILURE) {
return;
}

if (argc == 2) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}

bc_init_num(&result TSRMLS_CC);
php_str2num(&result, left TSRMLS_CC);

if (bc_sqrt (&result, scale TSRMLS_CC) != 0) {
if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}
Z_STRVAL_P(return_value) = bc_num2str(result);
Expand Down Expand Up @@ -531,7 +553,7 @@ PHP_FUNCTION(bccomp)
if (zend_parse_parameters(argc TSRMLS_CC, "ss|l", &left, &left_len, &right, &right_len, &scale_param) == FAILURE) {
return;
}

if (argc == 3) {
scale = (int) ((int)scale_param < 0) ? 0 : scale_param;
}
Expand All @@ -555,7 +577,7 @@ PHP_FUNCTION(bccomp)
PHP_FUNCTION(bcscale)
{
long new_scale;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &new_scale) == FAILURE) {
return;
}
Expand Down
13 changes: 13 additions & 0 deletions ext/bcmath/tests/bug72093.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--TEST--
Bug 72093: bcpowmod accepts negative scale and corrupts _one_ definition
--SKIPIF--
<?php if(!extension_loaded("bcmath")) print "skip"; ?>
--FILE--
<?php
var_dump(bcpowmod(1, "A", 128, -200));
var_dump(bcpowmod(1, 1.2, 1, 1));
?>
--EXPECTF--
string(1) "1"
bc math warning: non-zero scale in exponent
string(3) "0.0"
17 changes: 15 additions & 2 deletions ext/exif/exif.c
Original file line number Diff line number Diff line change
Expand Up @@ -2955,7 +2955,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
/* When there are any characters after the first NUL */
ImageInfo->CopyrightPhotographer = estrdup(value_ptr);
ImageInfo->CopyrightEditor = estrndup(value_ptr+length+1, byte_count-length-1);
spprintf(&ImageInfo->Copyright, 0, "%s, %s", value_ptr, value_ptr+length+1);
spprintf(&ImageInfo->Copyright, 0, "%s, %s", ImageInfo->CopyrightPhotographer, ImageInfo->CopyrightEditor);
/* format = TAG_FMT_UNDEFINED; this musn't be ASCII */
/* but we are not supposed to change this */
/* keep in mind that image_info does not store editor value */
Expand Down Expand Up @@ -3124,6 +3124,11 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,

ImageInfo->sections_found |= FOUND_IFD0;

if ((dir_start + 2) >= (offset_base+IFDlength)) {
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size");
return FALSE;
}

NumDirEntries = php_ifd_get16u(dir_start, ImageInfo->motorola_intel);

if ((dir_start+2+NumDirEntries*12) > (offset_base+IFDlength)) {
Expand All @@ -3147,6 +3152,10 @@ static int exif_process_IFD_in_JPEG(image_info_type *ImageInfo, char *dir_start,
* Hack to make it process IDF1 I hope
* There are 2 IDFs, the second one holds the keys (0x0201 and 0x0202) to the thumbnail
*/
if ((dir_start+2+12*de + 4) >= (offset_base+IFDlength)) {
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size");
return FALSE;
}
NextDirOffset = php_ifd_get32u(dir_start+2+12*de, ImageInfo->motorola_intel);
if (NextDirOffset) {
/* the next line seems false but here IFDlength means length of all IFDs */
Expand Down Expand Up @@ -3196,9 +3205,13 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf,
}

/* Check the next two values for correctness. */
if (length < 8) {
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid TIFF start (1)");
return;
}
exif_value_2a = php_ifd_get16u(CharBuf+2, ImageInfo->motorola_intel);
offset_of_ifd = php_ifd_get32u(CharBuf+4, ImageInfo->motorola_intel);
if ( exif_value_2a != 0x2a || offset_of_ifd < 0x08) {
if (exif_value_2a != 0x2a || offset_of_ifd < 0x08) {
exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid TIFF start (1)");
return;
}
Expand Down
61 changes: 61 additions & 0 deletions ext/exif/tests/bug72094.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
--TEST--
Bug #72094: Out of bounds heap read access in exif header processing
--SKIPIF--
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
--FILE--
<?php
print_r(exif_read_data(__DIR__ . '/bug72094_1.jpg'));
print_r(exif_read_data(__DIR__ . '/bug72094_2.jpg'));
print_r(exif_read_data(__DIR__ . '/bug72094_3.jpg'));
print_r(exif_read_data(__DIR__ . '/bug72094_4.jpg'));
?>
DONE
--EXPECTF--
Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Process tag(x8298=Copyright ): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Illegal IFD offset in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): File structure corrupted in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_1.jpg): Invalid JPEG file in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_2.jpg): Illegal IFD size in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_2.jpg): File structure corrupted in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_2.jpg): Invalid JPEG file in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Illegal IFD size in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): File structure corrupted in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_3.jpg): Invalid JPEG file in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_4.jpg): Invalid TIFF start (1) in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_4.jpg): File structure corrupted in %s/bug72094.php on line %d

Warning: exif_read_data(bug72094_4.jpg): Invalid JPEG file in %s/bug72094.php on line %d
DONE
Binary file added ext/exif/tests/bug72094_1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ext/exif/tests/bug72094_2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ext/exif/tests/bug72094_3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ext/exif/tests/bug72094_4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions ext/gd/libgd/gd_gd2.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,15 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in
cidx = gdCalloc(sidx, 1);
for (i = 0; i < nc; i++) {
if (gdGetInt(&cidx[i].offset, in) != 1) {
gdFree(cidx);
goto fail1;
}
if (gdGetInt(&cidx[i].size, in) != 1) {
gdFree(cidx);
goto fail1;
}
if (cidx[i].offset < 0 || cidx[i].size < 0) {
gdFree(cidx);
goto fail1;
}
}
Expand Down
16 changes: 16 additions & 0 deletions ext/gd/tests/bug71912.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--TEST--
Bug #71912 (libgd: signedness vulnerability)
--SKIPIF--
<?php
if(!extension_loaded('gd')){ die('skip gd extension not available'); }
if(!function_exists('imagecreatefromgd2')) die('skip imagecreatefromgd2() not available');
?>
--FILE--
<?php
imagecreatefromgd2(__DIR__."/invalid_neg_size.gd2");
?>
OK
--EXPECTF--

Warning: imagecreatefromgd2(): '%s/invalid_neg_size.gd2' is not a valid GD2 file in %s/bug71912.php on line %d
OK
Binary file added ext/gd/tests/invalid_neg_size.gd2
Binary file not shown.
Loading

0 comments on commit e315a16

Please sign in to comment.