diff options
author | Stanislav Malyshev <stas@php.net> | 2016-06-20 21:26:33 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2016-06-20 21:26:33 -0700 |
commit | 3f627e580acfdaf0595ae3b115b8bec677f203ee (patch) | |
tree | 3bc845034558e80a1f35a9980bd883676cb9be08 | |
parent | b9ec171e7d25879d97473ca50197c4207420c276 (diff) | |
download | php-git-3f627e580acfdaf0595ae3b115b8bec677f203ee.tar.gz |
Fixed ##72433: Use After Free Vulnerability in PHP's GC algorithm and unserialize
-rw-r--r-- | Zend/tests/gc_024.phpt | 2 | ||||
-rw-r--r-- | ext/spl/spl_array.c | 11 | ||||
-rw-r--r-- | ext/standard/tests/strings/bug72433.phpt | 32 |
3 files changed, 44 insertions, 1 deletions
diff --git a/Zend/tests/gc_024.phpt b/Zend/tests/gc_024.phpt index 9a2ceb88f5..ca78da63d3 100644 --- a/Zend/tests/gc_024.phpt +++ b/Zend/tests/gc_024.phpt @@ -13,5 +13,5 @@ var_dump(gc_collect_cycles()); echo "ok\n"; ?> --EXPECT-- -int(1) +int(2) ok diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index c89cf4994b..4e03c408c6 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -831,6 +831,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); +} +/* }}} */ + 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); @@ -1961,6 +1971,7 @@ PHP_MINIT_FUNCTION(spl_array) spl_handler_ArrayObject.get_properties = spl_array_get_properties; 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.write_property = spl_array_write_property; spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr; diff --git a/ext/standard/tests/strings/bug72433.phpt b/ext/standard/tests/strings/bug72433.phpt new file mode 100644 index 0000000000..3a2c89701b --- /dev/null +++ b/ext/standard/tests/strings/bug72433.phpt @@ -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* + } +} |