Merge branch 'PHP-5.6' into PHP-7.0

* PHP-5.6:
  Fix bug #73737 FPE when parsing a tag format
  Fix bug #73773 - Seg fault when loading hostile phar
  Fix bug #73825 - Heap out of bounds read on unserialize in finish_nested_data()
  Fix bug #73768 - Memory corruption when loading hostile phar
  Fix int overflows in phar (bug #73764)
This commit is contained in:
Stanislav Malyshev 2017-01-02 21:01:35 -08:00
commit 7f0de1a138
11 changed files with 578 additions and 518 deletions

View File

@ -1297,7 +1297,7 @@ static size_t exif_convert_any_to_int(void *value, int format, int motorola_inte
if (s_den == 0) {
return 0;
} else {
return php_ifd_get32s(value, motorola_intel) / s_den;
return (size_t)((double)php_ifd_get32s(value, motorola_intel) / s_den);
}
case TAG_FMT_SSHORT: return php_ifd_get16u(value, motorola_intel);

View File

@ -0,0 +1,12 @@
--TEST--
Bug #73737 (Crash when parsing a tag format)
--SKIPIF--
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
--FILE--
<?php
$exif = exif_thumbnail(__DIR__ . '/bug73737.tiff');
var_dump($exif);
?>
--EXPECTF--
Warning: exif_thumbnail(bug73737.tiff): Error in TIFF: filesize(x0030) less than start of IFD dir(x10102) in %s line %d
bool(false)

Binary file not shown.

View File

@ -983,7 +983,6 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
/* if the alias is stored we enforce it (implicit overrides explicit) */
if (alias && alias_len && (alias_len != (int)tmp_len || strncmp(alias, buffer, tmp_len)))
{
buffer[tmp_len] = '\0';
php_stream_close(fp);
if (signature) {
@ -991,7 +990,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
}
if (error) {
spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%s\" under different alias \"%s\"", fname, buffer, alias);
spprintf(error, 0, "cannot load phar \"%s\" with implicit alias \"%.*s\" under different alias \"%s\"", fname, tmp_len, buffer, alias);
}
efree(savebuf);
@ -1057,7 +1056,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
entry.is_persistent = mydata->is_persistent;
for (manifest_index = 0; manifest_index < manifest_count; ++manifest_index) {
if (buffer + 4 > endbuffer) {
if (buffer + 28 > endbuffer) {
MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest entry)")
}
@ -1071,7 +1070,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, int fname_len, char
entry.manifest_pos = manifest_index;
}
if (entry.filename_len + 20 > endbuffer - buffer) {
if (entry.filename_len > endbuffer - buffer - 24) {
MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest entry)");
}

Binary file not shown.

View File

@ -0,0 +1,16 @@
--TEST--
Phar: PHP bug #73764: Crash while loading hostile phar archive
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--FILE--
<?php
chdir(__DIR__);
try {
$p = Phar::LoadPhar('bug73764.phar', 'alias.phar');
echo "OK\n";
} catch(PharException $e) {
echo $e->getMessage();
}
?>
--EXPECTF--
internal corruption of phar "%sbug73764.phar" (truncated manifest entry)

Binary file not shown.

View File

@ -0,0 +1,16 @@
--TEST--
Phar: PHP bug #73768: Memory corruption when loading hostile phar
--SKIPIF--
<?php if (!extension_loaded("phar")) die("skip"); ?>
--FILE--
<?php
chdir(__DIR__);
try {
$p = Phar::LoadPhar('bug73768.phar', 'alias.phar');
echo "OK\n";
} catch(PharException $e) {
echo $e->getMessage();
}
?>
--EXPECTF--
cannot load phar "%sbug73768.phar" with implicit alias "" under different alias "alias.phar"

View File

@ -0,0 +1,12 @@
--TEST--
Bug #73825 Heap out of bounds read on unserialize in finish_nested_data()
--FILE--
<?php
$obj = unserialize('O:8:"00000000":');
var_dump($obj);
?>
--EXPECTF--
Warning: Bad unserialize data in %sbug73825.php on line %d
Notice: unserialize(): Error at offset 13 of 15 bytes in %sbug73825.php on line %d
bool(false)

File diff suppressed because it is too large Load Diff

View File

@ -437,6 +437,11 @@ static inline zend_long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *
{
zend_long elements;
if( *p >= max - 2) {
zend_error(E_WARNING, "Bad unserialize data");
return -1;
}
elements = parse_iv2((*p) + 2, p);
(*p) += 2;
@ -446,8 +451,8 @@ static inline zend_long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *
} else {
/* If this class implements Serializable, it should not land here but in object_custom(). The passed string
obviously doesn't descend from the regular serializer. */
zend_error(E_WARNING, "Erroneous data format for unserializing '%s'", ZSTR_VAL(ce->name));
return 0;
zend_error(E_WARNING, "Erroneous data format for unserializing '%s'", ce->name);
return -1;
}
return elements;
@ -760,10 +765,14 @@ use_double:
}
"o:" iv ":" ["] {
long elements;
if (!var_hash) return 0;
return object_common2(UNSERIALIZE_PASSTHRU,
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
if (elements < 0) {
return 0;
}
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
object ":" uiv ":" ["] {
@ -905,6 +914,11 @@ object ":" uiv ":" ["] {
elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
if (elements < 0) {
efree(class_name);
return 0;
}
if (incomplete_class) {
php_store_class_name(rval, ZSTR_VAL(class_name), len2);
}