--- a/components/php/php56/patches/CVE-2015-6834_70172.patch Wed Aug 31 15:13:45 2016 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-# Source: upstream
-# https://bugs.php.net/bug.php?id=70172
-# http://git.php.net/?p=php-src.git;a=commit;h=e8429400d40e3c3aa4b22ba701991d698a2f3b2f
-# Patch to var_unserializer.c regenerated to remove inapplicable #line comments
-
-From e8429400d40e3c3aa4b22ba701991d698a2f3b2f Mon Sep 17 00:00:00 2001
-From: Stanislav Malyshev <[email protected]>
-Date: Mon, 31 Aug 2015 21:28:11 -0700
-Subject: [PATCH] Fix bug #70172 - Use After Free Vulnerability in
- unserialize()
-
----
- ext/standard/tests/serialize/bug70172.phpt | 52 ++++++++++++++++++++
- ext/standard/var.c | 23 +++++++--
- ext/standard/var_unserializer.c | 76 ++++++++++++++++--------------
- ext/standard/var_unserializer.re | 12 +++--
- 4 files changed, 121 insertions(+), 42 deletions(-)
- create mode 100644 ext/standard/tests/serialize/bug70172.phpt
-
-diff --git a/ext/standard/tests/serialize/bug70172.phpt b/ext/standard/tests/serialize/bug70172.phpt
-new file mode 100644
-index 0000000..0e9d7ed
---- /dev/null
-+++ b/ext/standard/tests/serialize/bug70172.phpt
-@@ -0,0 +1,52 @@
-+--TEST--
-+Bug #70172 - Use After Free Vulnerability in unserialize()
-+--FILE--
-+<?php
-+class obj implements Serializable {
-+ var $data;
-+ function serialize() {
-+ return serialize($this->data);
-+ }
-+ function unserialize($data) {
-+ $this->data = unserialize($data);
-+ }
-+}
-+
-+$fakezval = ptr2str(1122334455);
-+$fakezval .= ptr2str(0);
-+$fakezval .= "\x00\x00\x00\x00";
-+$fakezval .= "\x01";
-+$fakezval .= "\x00";
-+$fakezval .= "\x00\x00";
-+
-+$inner = 'r:2;';
-+$exploit = 'a:2:{i:0;i:1;i:1;C:3:"obj":'.strlen($inner).':{'.$inner.'}}';
-+
-+$data = unserialize($exploit);
-+
-+for ($i = 0; $i < 5; $i++) {
-+ $v[$i] = $fakezval.$i;
-+}
-+
-+var_dump($data);
-+
-+function ptr2str($ptr)
-+{
-+ $out = '';
-+ for ($i = 0; $i < 8; $i++) {
-+ $out .= chr($ptr & 0xff);
-+ $ptr >>= 8;
-+ }
-+ return $out;
-+}
-+?>
-+--EXPECTF--
-+array(2) {
-+ [0]=>
-+ int(1)
-+ [1]=>
-+ object(obj)#%d (1) {
-+ ["data"]=>
-+ int(1)
-+ }
-+}
-\ No newline at end of file
-diff --git a/ext/standard/var.c b/ext/standard/var.c
-index 7603ff2..33b976f 100644
---- a/ext/standard/var.c
-+++ b/ext/standard/var.c
-@@ -373,7 +373,7 @@ static int php_array_element_export(zval **zv TSRMLS_DC, int num_args, va_list a
-
- smart_str_appendc(buf, ',');
- smart_str_appendc(buf, '\n');
--
-+
- return 0;
- }
- /* }}} */
-@@ -392,7 +392,7 @@ static int php_object_element_export(zval **zv TSRMLS_DC, int num_args, va_list
- const char *pname;
- char *pname_esc;
- int pname_esc_len;
--
-+
- zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1,
- &class_name, &pname);
- pname_esc = php_addcslashes(pname, strlen(pname), &pname_esc_len, 0,
-@@ -469,7 +469,7 @@ PHPAPI void php_var_export_ex(zval **struc, int level, smart_str *buf TSRMLS_DC)
- buffer_append_spaces(buf, level - 1);
- }
- smart_str_appendc(buf, ')');
--
-+
- break;
-
- case IS_OBJECT:
-@@ -802,7 +802,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var
- BG(serialize_lock)++;
- res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);
- BG(serialize_lock)--;
--
-+
- if (EG(exception)) {
- if (retval_ptr) {
- zval_ptr_dtor(&retval_ptr);
-@@ -951,6 +951,8 @@ PHP_FUNCTION(unserialize)
- int buf_len;
- const unsigned char *p;
- php_unserialize_data_t var_hash;
-+ int oldlevel;
-+ zval *old_rval = return_value;
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) {
- RETURN_FALSE;
-@@ -970,6 +972,19 @@ PHP_FUNCTION(unserialize)
- }
- RETURN_FALSE;
- }
-+ if (return_value != old_rval) {
-+ /*
-+ * Terrible hack due to the fact that executor passes us zval *,
-+ * but unserialize with r/R wants to replace it with another zval *
-+ */
-+ zval_dtor(old_rval);
-+ *old_rval = *return_value;
-+ zval_copy_ctor(old_rval);
-+ var_push_dtor_no_addref(&var_hash, &return_value);
-+ var_push_dtor_no_addref(&var_hash, &old_rval);
-+ } else {
-+ var_push_dtor(&var_hash, &return_value);
-+ }
- PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
- }
- /* }}} */
---- var_unserializer.c.orig Wed Sep 9 13:59:27 2015
-+++ php-5.6.8/ext/standard/var_unserializer.c Wed Sep 9 14:02:03 2015
-@@ -67,7 +67,7 @@
-
- var_hash = (*var_hashx)->last_dtor;
- #if VAR_ENTRIES_DBG
-- fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval));
-+ fprintf(stderr, "var_push_dtor(%p, %ld): %d\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval));
- #endif
-
- if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
-@@ -92,7 +92,7 @@
- {
- var_entries *var_hash = (*var_hashx)->last_dtor;
- #if VAR_ENTRIES_DBG
-- fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
-+ fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
- #endif
-
- if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
-@@ -171,6 +171,9 @@
-
- while (var_hash) {
- for (i = 0; i < var_hash->used_slots; i++) {
-+#if VAR_ENTRIES_DBG
-+ fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_hash->data[i], Z_REFCOUNT_P(var_hash->data[i]));
-+#endif
- zval_ptr_dtor(&var_hash->data[i]);
- }
- next = var_hash->next;
-@@ -628,6 +631,7 @@
- zval **args[1];
- zval *arg_func_name;
-
-+ if (!var_hash) return 0;
- if (*start == 'C') {
- custom_object = 1;
- }
-@@ -783,6 +787,7 @@
- if (yych != '"') goto yy18;
- ++YYCURSOR;
- {
-+ if (!var_hash) return 0;
-
- INIT_PZVAL(*rval);
-
-@@ -813,6 +818,7 @@
- long elements = parse_iv(start + 2);
- /* use iv() not uiv() in order to check data range */
- *p = YYCURSOR;
-+ if (!var_hash) return 0;
-
- if (elements < 0) {
- return 0;
-@@ -1242,7 +1248,7 @@
- }
-
- if (*rval != NULL) {
-- zval_ptr_dtor(rval);
-+ var_push_dtor_no_addref(var_hash, rval);
- }
- *rval = *rval_ref;
- Z_ADDREF_PP(rval);
-diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
-index f02602c..ed82152 100644
---- a/ext/standard/var_unserializer.re
-+++ b/ext/standard/var_unserializer.re
-@@ -67,7 +67,7 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval **rval)
-
- var_hash = (*var_hashx)->last_dtor;
- #if VAR_ENTRIES_DBG
-- fprintf(stderr, "var_push_dtor(%ld): %d\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval));
-+ fprintf(stderr, "var_push_dtor(%p, %ld): %d\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval));
- #endif
-
- if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
-@@ -98,7 +98,7 @@ PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval **rv
-
- var_hash = (*var_hashx)->last_dtor;
- #if VAR_ENTRIES_DBG
-- fprintf(stderr, "var_push_dtor_no_addref(%ld): %d (%d)\n", var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
-+ fprintf(stderr, "var_push_dtor_no_addref(%p, %ld): %d (%d)\n", *rval, var_hash?var_hash->used_slots:-1L, Z_TYPE_PP(rval), Z_REFCOUNT_PP(rval));
- #endif
-
- if (!var_hash || var_hash->used_slots == VAR_ENTRIES_MAX) {
-@@ -177,6 +177,9 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx)
-
- while (var_hash) {
- for (i = 0; i < var_hash->used_slots; i++) {
-+#if VAR_ENTRIES_DBG
-+ fprintf(stderr, "var_destroy dtor(%p, %ld)\n", var_hash->data[i], Z_REFCOUNT_P(var_hash->data[i]));
-+#endif
- zval_ptr_dtor(&var_hash->data[i]);
- }
- next = var_hash->next;
-@@ -501,7 +504,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
- }
-
- if (*rval != NULL) {
-- zval_ptr_dtor(rval);
-+ var_push_dtor_no_addref(var_hash, rval);
- }
- *rval = *rval_ref;
- Z_ADDREF_PP(rval);
-@@ -660,6 +663,7 @@ use_double:
- long elements = parse_iv(start + 2);
- /* use iv() not uiv() in order to check data range */
- *p = YYCURSOR;
-+ if (!var_hash) return 0;
-
- if (elements < 0) {
- return 0;
-@@ -677,6 +681,7 @@ use_double:
- }
-
- "o:" iv ":" ["] {
-+ if (!var_hash) return 0;
-
- INIT_PZVAL(*rval);
-
-@@ -699,6 +704,7 @@ object ":" uiv ":" ["] {
- zval **args[1];
- zval *arg_func_name;
-
-+ if (!var_hash) return 0;
- if (*start == 'C') {
- custom_object = 1;
- }
---
-2.1.4
-
-