Skip to content

Commit

Permalink
Merge branch 'PHP-5.6' into PHP-7.0
Browse files Browse the repository at this point in the history
* PHP-5.6:
  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
  • Loading branch information
weltling committed Apr 27, 2016
2 parents a32e143 + e315a16 commit 33d41da
Show file tree
Hide file tree
Showing 15 changed files with 199 additions and 35 deletions.
21 changes: 21 additions & 0 deletions ext/bcmath/bcmath.c
Expand Up @@ -207,6 +207,21 @@ static void php_str2num(bc_num *num, char *str)
}
/* }}} */

/* {{{ 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 @@ -233,6 +248,7 @@ PHP_FUNCTION(bcadd)
bc_add (first, second, &result, scale);

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

Expand Down Expand Up @@ -270,6 +286,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 Down Expand Up @@ -307,6 +324,7 @@ PHP_FUNCTION(bcmul)
bc_multiply (first, second, &result, scale);

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

Expand Down Expand Up @@ -345,6 +363,7 @@ PHP_FUNCTION(bcdiv)
switch (bc_divide(first, second, &result, scale)) {
case 0: /* OK */
if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}
RETVAL_STR(bc_num2str(result));
Expand Down Expand Up @@ -462,6 +481,7 @@ PHP_FUNCTION(bcpow)
bc_raise (first, second, &result, scale);

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

Expand Down Expand Up @@ -496,6 +516,7 @@ PHP_FUNCTION(bcsqrt)

if (bc_sqrt (&result, scale) != 0) {
if (result->n_scale > scale) {
result = split_bc_num(result);
result->n_scale = scale;
}
RETVAL_STR(bc_num2str(result));
Expand Down
13 changes: 13 additions & 0 deletions ext/bcmath/tests/bug72093.phpt
@@ -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
Expand Up @@ -2946,7 +2946,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 @@ -3115,6 +3115,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 @@ -3138,6 +3143,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 @@ -3187,9 +3196,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
@@ -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
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
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
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
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
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
@@ -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.
8 changes: 5 additions & 3 deletions ext/intl/grapheme/grapheme_string.c
Expand Up @@ -110,7 +110,7 @@ PHP_FUNCTION(grapheme_strpos)
size_t haystack_len, needle_len;
const char *found;
zend_long loffset = 0;
int32_t offset = 0;
int32_t offset = 0, noffset = 0;
zend_long ret_pos;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss|l", &haystack, &haystack_len, &needle, &needle_len, &loffset) == FAILURE) {
Expand All @@ -126,6 +126,7 @@ PHP_FUNCTION(grapheme_strpos)

/* we checked that it will fit: */
offset = (int32_t) loffset;
noffset = offset >= 0 ? offset : haystack_len + offset;

/* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */

Expand All @@ -138,7 +139,7 @@ PHP_FUNCTION(grapheme_strpos)
/* quick check to see if the string might be there
* I realize that 'offset' is 'grapheme count offset' but will work in spite of that
*/
found = php_memnstr(haystack + offset, needle, needle_len, haystack + haystack_len);
found = php_memnstr(haystack + noffset, needle, needle_len, haystack + haystack_len);

/* if it isn't there the we are done */
if (!found) {
Expand Down Expand Up @@ -199,12 +200,13 @@ PHP_FUNCTION(grapheme_stripos)
is_ascii = ( grapheme_ascii_check((unsigned char*)haystack, haystack_len) >= 0 );

if ( is_ascii ) {
int32_t noffset = offset >= 0 ? offset : haystack_len + offset;
needle_dup = estrndup(needle, needle_len);
php_strtolower(needle_dup, needle_len);
haystack_dup = estrndup(haystack, haystack_len);
php_strtolower(haystack_dup, haystack_len);

found = php_memnstr(haystack_dup + offset, needle_dup, needle_len, haystack_dup + haystack_len);
found = php_memnstr(haystack_dup + noffset, needle_dup, needle_len, haystack_dup + haystack_len);

efree(haystack_dup);
efree(needle_dup);
Expand Down
15 changes: 15 additions & 0 deletions ext/intl/tests/bug72061.phpt
@@ -0,0 +1,15 @@
--TEST--
Bug #72061: Out-of-bounds reads in zif_grapheme_stripos with negative offset
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
<?php

var_dump(grapheme_stripos(str_repeat("ABCD", 16384), "A", -201));
var_dump(grapheme_strpos(str_repeat("ABCD", 16384), "A", -201));
?>
DONE
--EXPECT--
int(65336)
int(65336)
DONE
17 changes: 17 additions & 0 deletions ext/xml/tests/bug72099.phpt
@@ -0,0 +1,17 @@
--TEST--
Bug #72099: xml_parse_into_struct segmentation fault
--SKIPIF--
<?php
require_once("skipif.inc");
?>
--FILE--
<?php
$var1=xml_parser_create_ns();
$var2=str_repeat("a", 10);
$var3=[];
$var4=[];
xml_parse_into_struct($var1, $var2, $var3, $var4);
var_dump($var3);
--EXPECT--
array(0) {
}

0 comments on commit 33d41da

Please sign in to comment.