From: Xinchen Hui Date: Thu, 12 May 2016 05:15:33 +0000 (+0800) Subject: Fixed bug #72195 (pg_pconnect/pg_connect cause use-after-free) X-Git-Tag: php-7.0.8RC1~71 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c0341e6f9c802ff50cc4eb08e6b90793d033aad;p=php Fixed bug #72195 (pg_pconnect/pg_connect cause use-after-free) --- diff --git a/NEWS b/NEWS index 1847b2d2c5..7472654778 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2016 PHP 7.0.8 +- Postgres: + . Fixed bug #72195 (pg_pconnect/pg_connect cause use-after-free). (Laruence) + - PDO_pgsql: . Fixed bug #71573 (Segfault (core dumped) if paramno beyond bound). (Laruence) diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index c196c97ee7..76dfd2a9e5 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1300,7 +1300,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) smart_str_append_long(&str, Z_LVAL(args[1]) ^ PGSQL_CONNECT_FORCE_NEW); } } - convert_to_string_ex(&args[i]); + ZVAL_STR(&args[i], zval_get_string(&args[i])); smart_str_appendc(&str, '_'); smart_str_appendl(&str, Z_STRVAL(args[i]), Z_STRLEN(args[i])); } @@ -1327,7 +1327,6 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) break; } } - efree(args); if (persistent && PGG(allow_persistent)) { zend_resource *le; @@ -1371,7 +1370,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) PGG(num_persistent)++; } else { /* we do */ if (le->type != le_plink) { - RETURN_FALSE; + goto err; } /* ensure that the link did not die */ if (PGG(auto_reset_persistent) & 1) { @@ -1422,7 +1421,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) zend_resource *link; if (index_ptr->type != le_index_ptr) { - RETURN_FALSE; + goto err; } link = (zend_resource *)index_ptr->ptr; @@ -1488,10 +1487,18 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) php_pgsql_set_default_link(Z_RES_P(return_value)); cleanup: + for (i = 0; i < ZEND_NUM_ARGS(); i++) { + zval_dtor(&args[i]); + } + efree(args); smart_str_free(&str); return; err: + for (i = 0; i < ZEND_NUM_ARGS(); i++) { + zval_dtor(&args[i]); + } + efree(args); smart_str_free(&str); RETURN_FALSE; } diff --git a/ext/pgsql/tests/bug72195.phpt b/ext/pgsql/tests/bug72195.phpt new file mode 100644 index 0000000000..2f33e1ab1c --- /dev/null +++ b/ext/pgsql/tests/bug72195.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #72195 (pg_pconnect/pg_connect cause use-after-free) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +0 +0 diff --git a/ext/pgsql/tests/config.inc b/ext/pgsql/tests/config.inc index e9944de793..7be1e242ad 100644 --- a/ext/pgsql/tests/config.inc +++ b/ext/pgsql/tests/config.inc @@ -5,7 +5,7 @@ // environment var PGSQL_TEST_CONNSTR // "test" database must exist. i.e. "createdb test" before testing -$conn_str = getenv('PGSQL_TEST_CONNSTR') ?: "host=localhost dbname=test port=5432"; // connection string +$conn_str = getenv('PGSQL_TEST_CONNSTR') ?: "host=localhost dbname=test port=5432 user=postgres password=postgres"; // connection string $table_name = "php_pgsql_test"; // test table that will be created $table_name_92 = "php_pgsql_test_92"; // test table that will be created