]> granicus.if.org Git - php/commitdiff
Fix bug #77955
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 23 May 2019 10:29:08 +0000 (12:29 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 23 May 2019 11:40:52 +0000 (13:40 +0200)
Free metadata before freeing the arena. I don't have a repro script,
but the added assertion fails for many existing tests prior to this
change.

NEWS
Zend/zend_arena.h
ext/mysqlnd/mysqlnd_result.c

diff --git a/NEWS b/NEWS
index a62c9dd8812627397ac41cd37bc9b05bd3f36ec0..7ddff4c431fb7f716df4ee59f978ebc093fffb7f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ PHP                                                                        NEWS
   . Fixed bug #77956 (When mysqli.allow_local_infile = Off, use a meaningful
     error message). (Sjon Hortensius)
 
+- MySQLnd:
+  . Fixed bug #77955 (Random segmentation fault in mysqlnd from php-fpm).
+    (Nikita)
+
 - Opcache:
   . Fixed bug #78015 (Incorrect evaluation of expressions involving partials
     arrays in SCCP). (Nikita)
index f83a5103cea71d3c94943fdb7922a32865fbbb47..604285fc97e2fd292f23e7829e4ec286c091872d 100644 (file)
@@ -110,6 +110,17 @@ static zend_always_inline void zend_arena_release(zend_arena **arena_ptr, void *
        arena->ptr = (char*)checkpoint;
 }
 
+static zend_always_inline zend_bool zend_arena_contains(zend_arena *arena, void *ptr)
+{
+       while (arena) {
+               if ((char*)ptr > (char*)arena && (char*)ptr <= arena->ptr) {
+                       return 1;
+               }
+               arena = arena->prev;
+       }
+       return 0;
+}
+
 #endif /* _ZEND_ARENA_H_ */
 
 /*
index f0852af360b16406082f32e38089011da5c0a9df..06a7793c9acdc4f80cfff39808febd84c8ad3cf9 100644 (file)
@@ -294,13 +294,14 @@ void MYSQLND_METHOD(mysqlnd_res, free_result_contents_internal)(MYSQLND_RES * re
 {
        DBG_ENTER("mysqlnd_res::free_result_contents_internal");
 
-       result->m.free_result_buffers(result);
-
        if (result->meta) {
+               ZEND_ASSERT(zend_arena_contains(result->memory_pool->arena, result->meta));
                result->meta->m->free_metadata(result->meta);
                result->meta = NULL;
        }
 
+       result->m.free_result_buffers(result);
+
        DBG_VOID_RETURN;
 }
 /* }}} */