114 lines
3.8 KiB
Diff
114 lines
3.8 KiB
Diff
From 3f627e580acfdaf0595ae3b115b8bec677f203ee Mon Sep 17 00:00:00 2001
|
|
From: Stanislav Malyshev <stas@php.net>
|
|
Date: Mon, 20 Jun 2016 21:26:33 -0700
|
|
Subject: [PATCH] Fixed ##72433: Use After Free Vulnerability in PHP's GC
|
|
algorithm and unserialize
|
|
|
|
---
|
|
Zend/tests/gc_024.phpt | 2 +-
|
|
ext/spl/spl_array.c | 11 +++++++++++
|
|
ext/standard/tests/strings/bug72433.phpt | 32 ++++++++++++++++++++++++++++++++
|
|
3 files changed, 44 insertions(+), 1 deletion(-)
|
|
create mode 100644 ext/standard/tests/strings/bug72433.phpt
|
|
|
|
diff --git a/Zend/tests/gc_024.phpt b/Zend/tests/gc_024.phpt
|
|
index 9a2ceb8..ca78da6 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 c89cf49..4e03c40 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);
|
|
@@ -1973,6 +1983,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 0000000..3a2c897
|
|
--- /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*
|
|
+ }
|
|
+}
|
|
From 7f428cae88f1294052087e6729f1ecb924b8a18d Mon Sep 17 00:00:00 2001
|
|
From: Stanislav Malyshev <stas@php.net>
|
|
Date: Mon, 20 Jun 2016 22:13:31 -0700
|
|
Subject: [PATCH] fix build
|
|
|
|
---
|
|
ext/spl/spl_array.c | 2 +-
|
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
|
|
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
|
|
index 4e03c40..5cb7d34 100644
|
|
--- a/ext/spl/spl_array.c
|
|
+++ b/ext/spl/spl_array.c
|
|
@@ -837,7 +837,7 @@ static HashTable *spl_array_get_gc(zval *object, zval ***gc_data, int *gc_data_c
|
|
|
|
*gc_data = &intern->array;
|
|
*gc_data_count = 1;
|
|
- return zend_std_get_properties(object);
|
|
+ return zend_std_get_properties(object TSRMLS_CC);
|
|
}
|
|
/* }}} */
|
|
|