]> granicus.if.org Git - php/commitdiff
Complete the fix of bug #70172 for PHP 7
authorNikita Popov <nikic@php.net>
Sun, 23 Oct 2016 19:37:36 +0000 (21:37 +0200)
committerNikita Popov <nikic@php.net>
Sat, 5 Nov 2016 22:06:27 +0000 (23:06 +0100)
ext/standard/tests/serialize/bug70172_2.phpt
ext/standard/var.c

index dc9067168a08110d9efb8cf23074ac244690ebbe..2b12a78edb5be332c0fbef46a76402a58125dbcf 100644 (file)
@@ -1,7 +1,5 @@
 --TEST--
 Bug #70172 - Use After Free Vulnerability in unserialize()
---XFAIL--
-Unfinished merge, needs fix.
 --FILE--
 <?php
 class obj implements Serializable {
@@ -61,10 +59,10 @@ array(2) {
     [0]=>
     array(1) {
       [0]=>
-      &object(obj2)#%d (1) {
+      object(obj2)#%d (1) {
         ["ryat"]=>
         int(1)
       }
     }
   }
-}
\ No newline at end of file
+}
index 472cd62d8f57bca6815a81c87bb80913f5425513..88719ccb64dcdb8f19723775a63f079debe6261f 100644 (file)
@@ -1036,6 +1036,7 @@ PHP_FUNCTION(unserialize)
        const unsigned char *p;
        php_unserialize_data_t var_hash;
        zval *options = NULL, *classes = NULL;
+       zval *retval;
        HashTable *class_hash = NULL;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|a", &buf, &buf_len, &options) == FAILURE) {
@@ -1067,22 +1068,21 @@ PHP_FUNCTION(unserialize)
                }
        }
 
-       if (!php_var_unserialize_ex(return_value, &p, p + buf_len, &var_hash, class_hash)) {
+       retval = var_tmp_var(&var_hash);
+       if (!php_var_unserialize_ex(retval, &p, p + buf_len, &var_hash, class_hash)) {
                PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
                if (class_hash) {
                        zend_hash_destroy(class_hash);
                        FREE_HASHTABLE(class_hash);
                }
-               zval_ptr_dtor(return_value);
                if (!EG(exception)) {
                        php_error_docref(NULL, E_NOTICE, "Error at offset " ZEND_LONG_FMT " of %zd bytes",
                                (zend_long)((char*)p - buf), buf_len);
                }
                RETURN_FALSE;
        }
-       /* We should keep an reference to return_value to prevent it from being dtor
-          in case nesting calls to unserialize */
-       var_push_dtor(&var_hash, return_value);
+
+       ZVAL_COPY(return_value, retval);
 
        PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
        if (class_hash) {