Skip to content

Commit f6aef68

Browse files
committed
Fix bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize
1 parent 3f627e5 commit f6aef68

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

Diff for: ext/standard/tests/strings/bug72434.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug #72434: ZipArchive class Use After Free Vulnerability in PHP's GC algorithm and unserialize
3+
--SKIPIF--
4+
<?php
5+
if(!class_exists('zip')) die('ZipArchive');
6+
?>
7+
--FILE--
8+
<?php
9+
// The following array will be serialized and this representation will be freed later on.
10+
$free_me = array(new StdClass());
11+
// Create our payload and unserialize it.
12+
$serialized_payload = 'a:3:{i:1;N;i:2;O:10:"ZipArchive":1:{s:8:"filename";'.serialize($free_me).'}i:1;R:4;}';
13+
$unserialized_payload = unserialize($serialized_payload);
14+
gc_collect_cycles();
15+
// The reference counter for $free_me is at -1 for PHP 7 right now.
16+
// Increment the reference counter by 1 -> rc is 0
17+
$a = $unserialized_payload[1];
18+
// Increment the reference counter by 1 again -> rc is 1
19+
$b = $a;
20+
// Trigger free of $free_me (referenced by $m[1]).
21+
unset($b);
22+
$fill_freed_space_1 = "filler_zval_1";
23+
$fill_freed_space_2 = "filler_zval_2";
24+
$fill_freed_space_3 = "filler_zval_3";
25+
$fill_freed_space_4 = "filler_zval_4";
26+
debug_zval_dump($unserialized_payload[1]);
27+
?>
28+
--EXPECTF--
29+
array(1) refcount(1){
30+
[0]=>
31+
object(stdClass)#%d (0) refcount(3){
32+
}
33+
}

Diff for: ext/zip/php_zip.c

+9
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,14 @@ static int php_zip_has_property(zval *object, zval *member, int type, const zend
10151015
}
10161016
/* }}} */
10171017

1018+
static HashTable *php_zip_get_gc(zval *object, zval ***gc_data, int *gc_data_count TSRMLS_DC) /* {{{ */
1019+
{
1020+
*gc_data = NULL;
1021+
*gc_data_count = 0;
1022+
return zend_std_get_properties(object TSRMLS_CC);
1023+
}
1024+
/* }}} */
1025+
10181026
static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */
10191027
{
10201028
ze_zip_object *obj;
@@ -2777,6 +2785,7 @@ static PHP_MINIT_FUNCTION(zip)
27772785
zip_object_handlers.clone_obj = NULL;
27782786
zip_object_handlers.get_property_ptr_ptr = php_zip_get_property_ptr_ptr;
27792787

2788+
zip_object_handlers.get_gc = php_zip_get_gc;
27802789
zip_object_handlers.get_properties = php_zip_get_properties;
27812790
zip_object_handlers.read_property = php_zip_read_property;
27822791
zip_object_handlers.has_property = php_zip_has_property;

0 commit comments

Comments
 (0)