andrey Tue Jun 24 13:19:30 2008 UTC Modified files: (Branch: PHP_5_3) /php-src/ext/mysql php_mysql.c /php-src/ext/mysqli mysqli.c /php-src/ext/mysqlnd mysqlnd.c mysqlnd_palloc.c Log: Fix double-free, introduced lately http://cvs.php.net/viewvc.cgi/php-src/ext/mysql/php_mysql.c?r1=1.213.2.6.2.16.2.18&r2=1.213.2.6.2.16.2.19&diff_format=u Index: php-src/ext/mysql/php_mysql.c diff -u php-src/ext/mysql/php_mysql.c:1.213.2.6.2.16.2.18 php-src/ext/mysql/php_mysql.c:1.213.2.6.2.16.2.19 --- php-src/ext/mysql/php_mysql.c:1.213.2.6.2.16.2.18 Tue Jun 24 11:01:38 2008 +++ php-src/ext/mysql/php_mysql.c Tue Jun 24 13:19:29 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mysql.c,v 1.213.2.6.2.16.2.18 2008/06/24 11:01:38 andrey Exp $ */ +/* $Id: php_mysql.c,v 1.213.2.6.2.16.2.19 2008/06/24 13:19:29 andrey Exp $ */ /* TODO: * @@ -365,6 +365,9 @@ void (*handler) (int); handler = signal(SIGPIPE, SIG_IGN); +#ifdef MYSQL_USE_MYSQLND + mysqlnd_end_psession(link->conn); +#endif mysql_close(link->conn); signal(SIGPIPE, handler); @@ -775,11 +778,12 @@ /* ensure that the link did not die */ if (mysql_ping(mysql->conn)) { if (mysql_errno(mysql->conn) == 2006) { -#ifndef MYSQL_USE_MYSQLND - if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) -#else +#ifdef MYSQL_USE_MYSQLND + mysqlnd_end_psession(mysql->conn); if (mysqlnd_connect(mysql->conn, host, user, passwd, 0, NULL, 0, port, socket, client_flags, MySG(mysqlnd_thd_zval_cache) TSRMLS_CC) == NULL) +#else + if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL) #endif { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect"); http://cvs.php.net/viewvc.cgi/php-src/ext/mysqli/mysqli.c?r1=1.72.2.16.2.17.2.24&r2=1.72.2.16.2.17.2.25&diff_format=u Index: php-src/ext/mysqli/mysqli.c diff -u php-src/ext/mysqli/mysqli.c:1.72.2.16.2.17.2.24 php-src/ext/mysqli/mysqli.c:1.72.2.16.2.17.2.25 --- php-src/ext/mysqli/mysqli.c:1.72.2.16.2.17.2.24 Tue May 6 17:05:14 2008 +++ php-src/ext/mysqli/mysqli.c Tue Jun 24 13:19:29 2008 @@ -17,7 +17,7 @@ | Ulf Wendel <[EMAIL PROTECTED]> | +----------------------------------------------------------------------+ - $Id: mysqli.c,v 1.72.2.16.2.17.2.24 2008/05/06 17:05:14 andrey Exp $ + $Id: mysqli.c,v 1.72.2.16.2.17.2.25 2008/06/24 13:19:29 andrey Exp $ */ #ifdef HAVE_CONFIG_H @@ -232,6 +232,9 @@ MY_MYSQL *mysql = (MY_MYSQL *)my_res->ptr; if (mysql->mysql) { if (!mysql->persistent) { +#ifdef MYSQLI_USE_MYSQLND + mysqlnd_end_psession(mysql->mysql); +#endif mysqli_close(mysql->mysql, MYSQLI_CLOSE_IMPLICIT); } else { zend_rsrc_list_entry *le; http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd.c?r1=1.5.2.21&r2=1.5.2.22&diff_format=u Index: php-src/ext/mysqlnd/mysqlnd.c diff -u php-src/ext/mysqlnd/mysqlnd.c:1.5.2.21 php-src/ext/mysqlnd/mysqlnd.c:1.5.2.22 --- php-src/ext/mysqlnd/mysqlnd.c:1.5.2.21 Tue Jun 24 11:01:38 2008 +++ php-src/ext/mysqlnd/mysqlnd.c Tue Jun 24 13:19:29 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd.c,v 1.5.2.21 2008/06/24 11:01:38 andrey Exp $ */ +/* $Id: mysqlnd.c,v 1.5.2.22 2008/06/24 13:19:29 andrey Exp $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -451,7 +451,11 @@ mnd_pefree(conn->last_message, conn->persistent); conn->last_message = NULL; } - conn->zval_cache = cache; + /* + The thd zval cache is always freed on request shutdown, so this has happened already. + Don't touch the old value! Get new reference + */ + conn->zval_cache = mysqlnd_palloc_get_thd_cache_reference(cache); DBG_VOID_RETURN; } /* }}} */ @@ -461,16 +465,8 @@ PHPAPI void _mysqlnd_end_psession(MYSQLND *conn TSRMLS_DC) { DBG_ENTER("_mysqlnd_end_psession"); - /* - BEWARE!!!! This will have a problem with a query cache. - We need to move the data out of the zval cache before we end the psession. - Or we will use nirvana pointers!! - */ - if (conn->zval_cache) { - DBG_INF("Freeing zval cache reference"); - mysqlnd_palloc_free_thd_cache_reference(&conn->zval_cache); - conn->zval_cache = NULL; - } + /* The thd zval cache is always freed on request shutdown, so this has happened already */ + conn->zval_cache = NULL; DBG_VOID_RETURN; } /* }}} */ http://cvs.php.net/viewvc.cgi/php-src/ext/mysqlnd/mysqlnd_palloc.c?r1=1.2.2.9&r2=1.2.2.10&diff_format=u Index: php-src/ext/mysqlnd/mysqlnd_palloc.c diff -u php-src/ext/mysqlnd/mysqlnd_palloc.c:1.2.2.9 php-src/ext/mysqlnd/mysqlnd_palloc.c:1.2.2.10 --- php-src/ext/mysqlnd/mysqlnd_palloc.c:1.2.2.9 Tue Jun 24 06:56:36 2008 +++ php-src/ext/mysqlnd/mysqlnd_palloc.c Tue Jun 24 13:19:29 2008 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_palloc.c,v 1.2.2.9 2008/06/24 06:56:36 andrey Exp $ */ +/* $Id: mysqlnd_palloc.c,v 1.2.2.10 2008/06/24 13:19:29 andrey Exp $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_priv.h" @@ -519,6 +519,15 @@ } /* + !!! 080624 !!! + If the user has used Persistent Connections the reference counter + of the cache is not 1 but > 1 . Because the Pconns don't are not signalised + during RSHUT, then we need to take care here to decrease the counter. + A more proper fix will be to array_walk our pconns in RSHUT and ask them to + free their thd reference. This should be implemented sooner or later! + */ + + /* Keep in mind that for pthreads pthread_equal() should be used to be fully standard compliant. However, the PHP code all-around, incl. the the Zend MM uses direct comparison. @@ -532,6 +541,8 @@ p = thd_cache->gc_list.ptr_line; LOCK_PCACHE(cache); + /* We need to decrease Main cache's references as pconns don't clean correctly */ + cache->references -= (thd_cache->references - 1); /* we start with 1 initial reference */ while (p < thd_cache->gc_list.last_added) { (*p)->point_type = MYSQLND_POINTS_FREE; *(--cache->free_list.last_added) = *p; @@ -543,6 +554,8 @@ } UNLOCK_PCACHE(cache); + /* We need to decrease thd cache's references as pconns don't clean correctly. See above! */ + thd_cache->references = 1; mysqlnd_palloc_free_thd_cache_reference(&thd_cache); DBG_VOID_RETURN;
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php