]> granicus.if.org Git - php/commitdiff
Fixed Bug #71859 (zend_objects_store_call_destructors operates on realloced memory...
authorXinchen Hui <laruence@gmail.com>
Sun, 20 Mar 2016 11:52:57 +0000 (04:52 -0700)
committerXinchen Hui <laruence@gmail.com>
Sun, 20 Mar 2016 11:52:57 +0000 (04:52 -0700)
NEWS
Zend/tests/bug71859.phpt [new file with mode: 0644]
Zend/zend_objects_API.c

diff --git a/NEWS b/NEWS
index 0a93b9824d6d29c445a7b4347a5597517e955403..d97e7c5a80a307f61f831267ac91539419626ac1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP                                                                        NEWS
 - Core: 
   . Added ability to disable huge pages in Zend Memory Manager through
     the environment variable USE_ZEND_ALLOC_HUGE_PAGES=0. (Dmitry)
+  . Fixed Bug #71859 (zend_objects_store_call_destructors operates on realloced
+    memory, crashing). (Laruence)
   . Fixed bug #71841 (EG(error_zval) is not handled well). (Laruence)
 
 - ODBC:
diff --git a/Zend/tests/bug71859.phpt b/Zend/tests/bug71859.phpt
new file mode 100644 (file)
index 0000000..5b62209
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #71859 (zend_objects_store_call_destructors operates on realloced memory, crashing)
+--FILE--
+<?php
+class constructs_in_destructor {
+  public function __destruct() {
+    //We are now in zend_objects_store_call_destructors
+    //This causes a realloc in zend_objects_store_put
+    for ($i = 0; $i < 10000; ++$i) {
+      $GLOBALS["a$i"] = new stdClass;
+    }
+    //Returns to zend_objects_store_call_destructors, to access freed memory.
+  }
+}
+
+$a = new constructs_in_destructor;
+//Create cycle so destructors are ran only in zend_objects_store_call_destructors
+$a->a = $a;
+
+// Create some objects so zend_objects_store_call_destructors has something
+// to do after constructs_in_destructor is destroyed.
+for ($i = 0; $i < 200; ++$i) {
+  $GLOBALS["b$i"] = new stdClass;
+}
+?>
+okey
+--EXPECT--
+okey
index 6ca190eabe8a3378b73c496e28873a7dbf7f8811..00d9425f18cd63dde3d7f10f442834f860c2b34e 100644 (file)
@@ -44,12 +44,9 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects)
 ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects)
 {
        if (objects->top > 1) {
-               zend_object **obj_ptr = objects->object_buckets + 1;
-               zend_object **end = objects->object_buckets + objects->top;
-
-               do {
-                       zend_object *obj = *obj_ptr;
-
+               uint32_t i;
+               for (i = 1; i < objects->top; i++) {
+                       zend_object *obj = objects->object_buckets[i];
                        if (IS_OBJ_VALID(obj)) {
                                if (!(GC_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
                                        GC_FLAGS(obj) |= IS_OBJ_DESTRUCTOR_CALLED;
@@ -58,8 +55,7 @@ ZEND_API void zend_objects_store_call_destructors(zend_objects_store *objects)
                                        GC_REFCOUNT(obj)--;
                                }
                        }
-                       obj_ptr++;
-               } while (obj_ptr != end);
+               }
        }
 }