mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-5.5' into PHP-5.6.23
* PHP-5.5: Fixed bug #72446 - Integer Overflow in gdImagePaletteToTrueColor() resulting in heap overflow update NEWS fix tests fix build Fix bug #72455: Heap Overflow due to integer overflows Fix bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize Fixed ##72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize Fix bug #72407: NULL Pointer Dereference at _gdScaleVert Fix bug #72402: _php_mb_regex_ereg_replace_exec - double free Fix bug #72298 pass2_no_dither out-of-bounds access Fixed #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow Fix bug #72262 - do not overflow int Fix bug #72400 and #72403 - prevent signed int overflows for string lengths Fix bug #72275: don't allow smart_str to overflow int Fix bug #72340: Double Free Courruption in wddx_deserialize update NEWS Fix #66387: Stack overflow with imagefilltoborder Skip test which is 64bits only 5.5.37 now Conflicts: configure.in ext/mcrypt/mcrypt.c ext/spl/spl_directory.c main/php_version.h
This commit is contained in:
commit
7dde353ee7
21 changed files with 450 additions and 243 deletions
|
@ -13,5 +13,5 @@ var_dump(gc_collect_cycles());
|
||||||
echo "ok\n";
|
echo "ok\n";
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
int(1)
|
int(2)
|
||||||
ok
|
ok
|
||||||
|
|
|
@ -133,6 +133,10 @@ gdImagePtr gdImageCreate (int sx, int sy)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (overflow2(sizeof(unsigned char *), sx)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
im = (gdImage *) gdCalloc(1, sizeof(gdImage));
|
im = (gdImage *) gdCalloc(1, sizeof(gdImage));
|
||||||
|
|
||||||
/* Row-major ever since gd 1.3 */
|
/* Row-major ever since gd 1.3 */
|
||||||
|
|
|
@ -138,11 +138,18 @@ static int _gd2GetHeader(gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, in
|
||||||
if (gd2_compressed(*fmt)) {
|
if (gd2_compressed(*fmt)) {
|
||||||
nc = (*ncx) * (*ncy);
|
nc = (*ncx) * (*ncy);
|
||||||
GD2_DBG(php_gd_error("Reading %d chunk index entries", nc));
|
GD2_DBG(php_gd_error("Reading %d chunk index entries", nc));
|
||||||
|
if (overflow2(sizeof(t_chunk_info), nc)) {
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
sidx = sizeof(t_chunk_info) * nc;
|
sidx = sizeof(t_chunk_info) * nc;
|
||||||
if (sidx <= 0) {
|
if (sidx <= 0) {
|
||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
cidx = gdCalloc(sidx, 1);
|
cidx = gdCalloc(sidx, 1);
|
||||||
|
if (cidx == NULL) {
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < nc; i++) {
|
for (i = 0; i < nc; i++) {
|
||||||
if (gdGetInt(&cidx[i].offset, in) != 1) {
|
if (gdGetInt(&cidx[i].offset, in) != 1) {
|
||||||
gdFree(cidx);
|
gdFree(cidx);
|
||||||
|
|
|
@ -1047,6 +1047,9 @@ static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_w
|
||||||
}
|
}
|
||||||
|
|
||||||
contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation);
|
contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation);
|
||||||
|
if (contrib == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* scale each column */
|
/* scale each column */
|
||||||
for (u = 0; u < dst_width - 1; u++) {
|
for (u = 0; u < dst_width - 1; u++) {
|
||||||
_gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);
|
_gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);
|
||||||
|
|
|
@ -1329,7 +1329,7 @@ pass2_no_dither (j_decompress_ptr cinfo,
|
||||||
/* If the pixel is transparent, we assign it the palette index that
|
/* If the pixel is transparent, we assign it the palette index that
|
||||||
* will later be added at the end of the palette as the transparent
|
* will later be added at the end of the palette as the transparent
|
||||||
* index. */
|
* index. */
|
||||||
if ((oim->transparent >= 0) && (oim->transparent == *(inptr - 1)))
|
if ((oim->transparent >= 0) && (oim->transparent == *inptr))
|
||||||
{
|
{
|
||||||
*outptr++ = nim->colorsTotal;
|
*outptr++ = nim->colorsTotal;
|
||||||
inptr++;
|
inptr++;
|
||||||
|
|
15
ext/gd/tests/bug72298.phpt
Normal file
15
ext/gd/tests/bug72298.phpt
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72298: pass2_no_dither out-of-bounds access
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded('gd')) die("skip gd extension not available\n");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$img = imagecreatetruecolor (1 , 1);
|
||||||
|
imagecolortransparent($img, 0);
|
||||||
|
imagetruecolortopalette($img, false, 4);
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECT--
|
||||||
|
DONE
|
BIN
ext/gd/tests/bug72339.gd
Normal file
BIN
ext/gd/tests/bug72339.gd
Normal file
Binary file not shown.
11
ext/gd/tests/bug72339.phpt
Normal file
11
ext/gd/tests/bug72339.phpt
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72339 Integer Overflow in _gd2GetHeader() resulting in heap overflow
|
||||||
|
--SKIPIF--
|
||||||
|
<?php if (!function_exists("imagecreatefromgd2")) print "skip"; ?>
|
||||||
|
--FILE--
|
||||||
|
<?php imagecreatefromgd2(dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug72339.gd"); ?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: imagecreatefromgd2(): gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully
|
||||||
|
in %sbug72339.php on line %d
|
||||||
|
|
||||||
|
Warning: imagecreatefromgd2(): '%sbug72339.gd' is not a valid GD2 file in %sbug72339.php on line %d
|
|
@ -953,7 +953,7 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
|
||||||
eval_buf.len = 0;
|
eval_buf.len = 0;
|
||||||
zval_dtor(&v);
|
zval_dtor(&v);
|
||||||
} else if (is_callable) {
|
} else if (is_callable) {
|
||||||
zval *retval_ptr;
|
zval *retval_ptr = NULL;
|
||||||
zval **args[1];
|
zval **args[1];
|
||||||
zval *subpats;
|
zval *subpats;
|
||||||
int i;
|
int i;
|
||||||
|
@ -972,13 +972,12 @@ static void _php_mb_regex_ereg_replace_exec(INTERNAL_FUNCTION_PARAMETERS, OnigOp
|
||||||
arg_replace_fci.param_count = 1;
|
arg_replace_fci.param_count = 1;
|
||||||
arg_replace_fci.params = args;
|
arg_replace_fci.params = args;
|
||||||
arg_replace_fci.retval_ptr_ptr = &retval_ptr;
|
arg_replace_fci.retval_ptr_ptr = &retval_ptr;
|
||||||
if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr) {
|
if (zend_call_function(&arg_replace_fci, &arg_replace_fci_cache TSRMLS_CC) == SUCCESS && arg_replace_fci.retval_ptr_ptr && retval_ptr) {
|
||||||
convert_to_string_ex(&retval_ptr);
|
convert_to_string_ex(&retval_ptr);
|
||||||
smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr));
|
smart_str_appendl(&out_buf, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr));
|
||||||
eval_buf.len = 0;
|
eval_buf.len = 0;
|
||||||
zval_ptr_dtor(&retval_ptr);
|
zval_ptr_dtor(&retval_ptr);
|
||||||
} else {
|
} else {
|
||||||
efree(description);
|
|
||||||
if (!EG(exception)) {
|
if (!EG(exception)) {
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call custom replacement function");
|
||||||
}
|
}
|
||||||
|
|
17
ext/mbstring/tests/bug72402.phpt
Normal file
17
ext/mbstring/tests/bug72402.phpt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72402: _php_mb_regex_ereg_replace_exec - double free
|
||||||
|
--SKIPIF--
|
||||||
|
<?php extension_loaded('mbstring') or die('skip mbstring not available'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
function throwit() {
|
||||||
|
throw new Exception('it');
|
||||||
|
}
|
||||||
|
$var10 = "throwit";
|
||||||
|
try {
|
||||||
|
$var14 = mb_ereg_replace_callback("", $var10, "");
|
||||||
|
} catch(Exception $e) {}
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECT--
|
||||||
|
DONE
|
|
@ -661,6 +661,10 @@ PHP_FUNCTION(mcrypt_generic)
|
||||||
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
||||||
block_size = mcrypt_enc_get_block_size(pm->td);
|
block_size = mcrypt_enc_get_block_size(pm->td);
|
||||||
data_size = (((data_len - 1) / block_size) + 1) * block_size;
|
data_size = (((data_len - 1) / block_size) + 1) * block_size;
|
||||||
|
if (data_size <= 0) {
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Integer overflow in data size");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
data_s = emalloc(data_size + 1);
|
data_s = emalloc(data_size + 1);
|
||||||
memset(data_s, 0, data_size);
|
memset(data_s, 0, data_size);
|
||||||
memcpy(data_s, data, data_len);
|
memcpy(data_s, data, data_len);
|
||||||
|
@ -706,6 +710,10 @@ PHP_FUNCTION(mdecrypt_generic)
|
||||||
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
|
||||||
block_size = mcrypt_enc_get_block_size(pm->td);
|
block_size = mcrypt_enc_get_block_size(pm->td);
|
||||||
data_size = (((data_len - 1) / block_size) + 1) * block_size;
|
data_size = (((data_len - 1) / block_size) + 1) * block_size;
|
||||||
|
if (data_size <= 0) {
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Integer overflow in data size");
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
data_s = emalloc(data_size + 1);
|
data_s = emalloc(data_size + 1);
|
||||||
memset(data_s, 0, data_size);
|
memset(data_s, 0, data_size);
|
||||||
memcpy(data_s, data, data_len);
|
memcpy(data_s, data, data_len);
|
||||||
|
|
|
@ -846,6 +846,16 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /*
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static HashTable *spl_array_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */
|
||||||
|
{
|
||||||
|
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
|
||||||
|
|
||||||
|
*gc_data = &intern->array;
|
||||||
|
*gc_data_count = 1;
|
||||||
|
return zend_std_get_properties(object TSRMLS_CC);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
static zval *spl_array_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
|
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
|
||||||
|
@ -1975,6 +1985,7 @@ PHP_MINIT_FUNCTION(spl_array)
|
||||||
|
|
||||||
spl_handler_ArrayObject.get_properties = spl_array_get_properties;
|
spl_handler_ArrayObject.get_properties = spl_array_get_properties;
|
||||||
spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info;
|
spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info;
|
||||||
|
spl_handler_ArrayObject.get_gc = spl_array_get_gc;
|
||||||
spl_handler_ArrayObject.read_property = spl_array_read_property;
|
spl_handler_ArrayObject.read_property = spl_array_read_property;
|
||||||
spl_handler_ArrayObject.write_property = spl_array_write_property;
|
spl_handler_ArrayObject.write_property = spl_array_write_property;
|
||||||
spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr;
|
spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr;
|
||||||
|
|
|
@ -2948,6 +2948,10 @@ SPL_METHOD(SplFileObject, fread)
|
||||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be greater than 0");
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
|
if (length > INT_MAX) {
|
||||||
|
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length parameter must be no more than %d", INT_MAX);
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
Z_STRVAL_P(return_value) = emalloc(length + 1);
|
Z_STRVAL_P(return_value) = emalloc(length + 1);
|
||||||
Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length);
|
Z_STRLEN_P(return_value) = php_stream_read(intern->u.file.stream, Z_STRVAL_P(return_value), length);
|
||||||
|
|
|
@ -63,6 +63,9 @@
|
||||||
newlen = (d)->len + (n); \
|
newlen = (d)->len + (n); \
|
||||||
if (newlen >= (d)->a) { \
|
if (newlen >= (d)->a) { \
|
||||||
(d)->a = newlen + SMART_STR_PREALLOC; \
|
(d)->a = newlen + SMART_STR_PREALLOC; \
|
||||||
|
if (UNEXPECTED((d)->a >= INT_MAX)) { \
|
||||||
|
zend_error(E_ERROR, "String size overflow"); \
|
||||||
|
} \
|
||||||
SMART_STR_DO_REALLOC(d, what); \
|
SMART_STR_DO_REALLOC(d, what); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -132,6 +132,9 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *
|
||||||
register unsigned char *result = NULL;
|
register unsigned char *result = NULL;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
|
|
||||||
|
if (UNEXPECTED(oldlen * 2 * sizeof(char) > INT_MAX)) {
|
||||||
|
zend_error(E_ERROR, "String size overflow");
|
||||||
|
}
|
||||||
result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1);
|
result = (unsigned char *) safe_emalloc(oldlen, 2 * sizeof(char), 1);
|
||||||
|
|
||||||
for (i = j = 0; i < oldlen; i++) {
|
for (i = j = 0; i < oldlen; i++) {
|
||||||
|
@ -2608,6 +2611,7 @@ PHP_FUNCTION(quotemeta)
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
char c;
|
char c;
|
||||||
int old_len;
|
int old_len;
|
||||||
|
size_t new_len;
|
||||||
|
|
||||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) {
|
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &old, &old_len) == FAILURE) {
|
||||||
return;
|
return;
|
||||||
|
@ -2642,8 +2646,13 @@ PHP_FUNCTION(quotemeta)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*q = 0;
|
*q = 0;
|
||||||
|
new_len = q - str;
|
||||||
|
if (UNEXPECTED(new_len > INT_MAX)) {
|
||||||
|
efree(str);
|
||||||
|
zend_error(E_ERROR, "String size overflow");
|
||||||
|
}
|
||||||
|
|
||||||
RETURN_STRINGL(erealloc(str, q - str + 1), q - str, 0);
|
RETURN_STRINGL(erealloc(str, new_len + 1), new_len, 0);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -3495,7 +3504,7 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s
|
||||||
char *source, *target;
|
char *source, *target;
|
||||||
char *end;
|
char *end;
|
||||||
char c;
|
char c;
|
||||||
int newlen;
|
size_t newlen;
|
||||||
|
|
||||||
if (!wlength) {
|
if (!wlength) {
|
||||||
wlength = strlen(what);
|
wlength = strlen(what);
|
||||||
|
@ -3526,11 +3535,15 @@ PHPAPI char *php_addcslashes(const char *str, int length, int *new_length, int s
|
||||||
}
|
}
|
||||||
*target = 0;
|
*target = 0;
|
||||||
newlen = target - new_str;
|
newlen = target - new_str;
|
||||||
|
if (UNEXPECTED(newlen > INT_MAX)) {
|
||||||
|
efree(new_str);
|
||||||
|
zend_error(E_ERROR, "String size overflow");
|
||||||
|
}
|
||||||
if (target - new_str < length * 4) {
|
if (target - new_str < length * 4) {
|
||||||
new_str = erealloc(new_str, newlen + 1);
|
new_str = erealloc(new_str, newlen + 1);
|
||||||
}
|
}
|
||||||
if (new_length) {
|
if (new_length) {
|
||||||
*new_length = newlen;
|
*new_length = (int)newlen;
|
||||||
}
|
}
|
||||||
if (should_free) {
|
if (should_free) {
|
||||||
STR_FREE((char*)str);
|
STR_FREE((char*)str);
|
||||||
|
@ -3582,6 +3595,9 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int should_f
|
||||||
|
|
||||||
*target = 0;
|
*target = 0;
|
||||||
*new_length = target - new_str;
|
*new_length = target - new_str;
|
||||||
|
if (UNEXPECTED(*new_length < 0)) {
|
||||||
|
zend_error(E_ERROR, "String size overflow");
|
||||||
|
}
|
||||||
if (should_free) {
|
if (should_free) {
|
||||||
STR_FREE(str);
|
STR_FREE(str);
|
||||||
}
|
}
|
||||||
|
@ -4285,6 +4301,9 @@ PHP_FUNCTION(nl2br)
|
||||||
size_t repl_len = is_xhtml ? (sizeof("<br />") - 1) : (sizeof("<br>") - 1);
|
size_t repl_len = is_xhtml ? (sizeof("<br />") - 1) : (sizeof("<br>") - 1);
|
||||||
|
|
||||||
new_length = str_len + repl_cnt * repl_len;
|
new_length = str_len + repl_cnt * repl_len;
|
||||||
|
if (UNEXPECTED(new_length > INT_MAX)) {
|
||||||
|
zend_error(E_ERROR, "String size overflow");
|
||||||
|
}
|
||||||
tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1);
|
tmp = target = safe_emalloc(repl_cnt, repl_len, str_len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
32
ext/standard/tests/strings/bug72433.phpt
Normal file
32
ext/standard/tests/strings/bug72433.phpt
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
// Fill any potential freed spaces until now.
|
||||||
|
$filler = array();
|
||||||
|
for($i = 0; $i < 100; $i++)
|
||||||
|
$filler[] = "";
|
||||||
|
// Create our payload and unserialize it.
|
||||||
|
$serialized_payload = 'a:3:{i:0;r:1;i:1;r:1;i:2;C:11:"ArrayObject":19:{x:i:0;r:1;;m:a:0:{}}}';
|
||||||
|
$free_me = unserialize($serialized_payload);
|
||||||
|
// We need to increment the reference counter of our ArrayObject s.t. all reference counters of our unserialized array become 0.
|
||||||
|
$inc_ref_by_one = $free_me[2];
|
||||||
|
// The call to gc_collect_cycles will free '$free_me'.
|
||||||
|
gc_collect_cycles();
|
||||||
|
// We now have multiple freed spaces. Fill all of them.
|
||||||
|
$fill_freed_space_1 = "filler_zval_1";
|
||||||
|
$fill_freed_space_2 = "filler_zval_2";
|
||||||
|
var_dump($free_me);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
array(3) {
|
||||||
|
[0]=>
|
||||||
|
*RECURSION*
|
||||||
|
[1]=>
|
||||||
|
*RECURSION*
|
||||||
|
[2]=>
|
||||||
|
object(ArrayObject)#%d (1) {
|
||||||
|
["storage":"ArrayObject":private]=>
|
||||||
|
*RECURSION*
|
||||||
|
}
|
||||||
|
}
|
33
ext/standard/tests/strings/bug72434.phpt
Normal file
33
ext/standard/tests/strings/bug72434.phpt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(!class_exists('zip')) die('ZipArchive');
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
// The following array will be serialized and this representation will be freed later on.
|
||||||
|
$free_me = array(new StdClass());
|
||||||
|
// Create our payload and unserialize it.
|
||||||
|
$serialized_payload = 'a:3:{i:1;N;i:2;O:10:"ZipArchive":1:{s:8:"filename";'.serialize($free_me).'}i:1;R:4;}';
|
||||||
|
$unserialized_payload = unserialize($serialized_payload);
|
||||||
|
gc_collect_cycles();
|
||||||
|
// The reference counter for $free_me is at -1 for PHP 7 right now.
|
||||||
|
// Increment the reference counter by 1 -> rc is 0
|
||||||
|
$a = $unserialized_payload[1];
|
||||||
|
// Increment the reference counter by 1 again -> rc is 1
|
||||||
|
$b = $a;
|
||||||
|
// Trigger free of $free_me (referenced by $m[1]).
|
||||||
|
unset($b);
|
||||||
|
$fill_freed_space_1 = "filler_zval_1";
|
||||||
|
$fill_freed_space_2 = "filler_zval_2";
|
||||||
|
$fill_freed_space_3 = "filler_zval_3";
|
||||||
|
$fill_freed_space_4 = "filler_zval_4";
|
||||||
|
debug_zval_dump($unserialized_payload[1]);
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
array(1) refcount(1){
|
||||||
|
[0]=>
|
||||||
|
object(stdClass)#%d (0) refcount(3){
|
||||||
|
}
|
||||||
|
}
|
|
@ -625,6 +625,10 @@ PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
|
||||||
if (new_length) {
|
if (new_length) {
|
||||||
*new_length = y;
|
*new_length = y;
|
||||||
}
|
}
|
||||||
|
if (UNEXPECTED(y > INT_MAX)) {
|
||||||
|
efree(str);
|
||||||
|
zend_error(E_ERROR, "String size overflow");
|
||||||
|
}
|
||||||
return ((char *) str);
|
return ((char *) str);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
24
ext/wddx/tests/bug72340.phpt
Normal file
24
ext/wddx/tests/bug72340.phpt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
--TEST--
|
||||||
|
Bug #72340: Double Free Courruption in wddx_deserialize
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (!extension_loaded("wddx")) print "skip";
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$xml = <<<EOF
|
||||||
|
<?xml version='1.0' ?>
|
||||||
|
<!DOCTYPE wddxPacket SYSTEM 'wddx_0100.dtd'>
|
||||||
|
<wddxPacket version='1.0'>
|
||||||
|
<array><var name="XXXXXXXX"><boolean value="none">TEST</boolean></var>
|
||||||
|
<var name="YYYYYYYY"><var name="ZZZZZZZZ"><var name="EZEZEZEZ">
|
||||||
|
</var></var></var>
|
||||||
|
</array>
|
||||||
|
</wddxPacket>
|
||||||
|
EOF;
|
||||||
|
$array = wddx_deserialize($xml);
|
||||||
|
var_dump($array);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array(0) {
|
||||||
|
}
|
|
@ -1094,6 +1094,9 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ST_BOOLEAN:
|
case ST_BOOLEAN:
|
||||||
|
if(!ent->data) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!strcmp(s, "true")) {
|
if (!strcmp(s, "true")) {
|
||||||
Z_LVAL_P(ent->data) = 1;
|
Z_LVAL_P(ent->data) = 1;
|
||||||
} else if (!strcmp(s, "false")) {
|
} else if (!strcmp(s, "false")) {
|
||||||
|
@ -1102,6 +1105,7 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len)
|
||||||
zval_ptr_dtor(&ent->data);
|
zval_ptr_dtor(&ent->data);
|
||||||
if (ent->varname) {
|
if (ent->varname) {
|
||||||
efree(ent->varname);
|
efree(ent->varname);
|
||||||
|
ent->varname = NULL;
|
||||||
}
|
}
|
||||||
ent->data = NULL;
|
ent->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1042,6 +1042,14 @@ static int php_zip_has_property(zval *object, zval *member, int type KEY_ARG_DC
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
static HashTable *php_zip_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */
|
||||||
|
{
|
||||||
|
*gc_data = NULL;
|
||||||
|
*gc_data_count = 0;
|
||||||
|
return zend_std_get_properties(object TSRMLS_CC);
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */
|
static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */
|
||||||
{
|
{
|
||||||
ze_zip_object *obj;
|
ze_zip_object *obj;
|
||||||
|
@ -3039,6 +3047,7 @@ static PHP_MINIT_FUNCTION(zip)
|
||||||
zip_object_handlers.clone_obj = NULL;
|
zip_object_handlers.clone_obj = NULL;
|
||||||
zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
|
zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
|
||||||
|
|
||||||
|
zip_object_handlers.get_gc = php_zip_get_gc;
|
||||||
zip_object_handlers.get_properties = php_zip_get_properties;
|
zip_object_handlers.get_properties = php_zip_get_properties;
|
||||||
zip_object_handlers.read_property = php_zip_read_property;
|
zip_object_handlers.read_property = php_zip_read_property;
|
||||||
zip_object_handlers.has_property = php_zip_has_property;
|
zip_object_handlers.has_property = php_zip_has_property;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue