Fixed a potential segfault in zend_objects_store_free_object_storage()
authorBob Weinand <bobwei9@hotmail.com>
Wed, 27 Jul 2016 16:08:43 +0000 (18:08 +0200)
committerBob Weinand <bobwei9@hotmail.com>
Wed, 27 Jul 2016 16:08:43 +0000 (18:08 +0200)
Under the special circumstance where a garbage collected objects bucket slot was not reused until the end of the script, we get access into freed memory...
No test added as it usually is valgrind-only, and only sometimes when the memory happens to have changed (i.e. (GC_FLAGS(obj) & IS_OBJ_FREE_CALLED) == 0), it actually *may* segfault

NEWS
Zend/zend_gc.c

diff --git a/NEWS b/NEWS
index abfb573c79eb23823479e49774a5fb18bd1d31bc..36f5f69d12e3ee6c7b68edabe83e50c363c5b7de 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@ PHP                                                                        NEWS
     phpize). (Yuji Uchiyama)
   . Fixed bug #72641 (phpize (on Windows) ignores PHP_PREFIX).
     (Yuji Uchiyama)
+  . Fixed potential segfault in object storage freeing in shutdown sequence.
+    (Bob)
 
 - COM:
   . Fixed bug #72569 (DOTNET/COM array parameters broke in PHP7). (Anatol)
index 821ac4d9dc6ae4f594ae98acf644d923ed16d831..95be5d80c07a6ce48aa64448db6bf380cef88b2b 100644 (file)
@@ -1097,6 +1097,7 @@ ZEND_API int zend_gc_collect_cycles(void)
 
                                if (EG(objects_store).object_buckets &&
                                    IS_OBJ_VALID(EG(objects_store).object_buckets[obj->handle])) {
+                                       EG(objects_store).object_buckets[obj->handle] = SET_OBJ_INVALID(obj);
                                        GC_TYPE(obj) = IS_NULL;
                                        if (!(GC_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
                                                GC_FLAGS(obj) |= IS_OBJ_FREE_CALLED;