diff options
| -rw-r--r-- | ext/pgsql/pgsql.c | 15 | ||||
| -rw-r--r-- | ext/pgsql/tests/bug72195.phpt | 17 | ||||
| -rw-r--r-- | ext/pgsql/tests/config.inc | 2 |
3 files changed, 29 insertions, 5 deletions
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 891861f1f7..816e9dba99 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1306,7 +1306,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])); } @@ -1333,7 +1333,6 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) break; } } - efree(args); if (persistent && PGG(allow_persistent)) { zend_resource *le; @@ -1377,7 +1376,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) { @@ -1428,7 +1427,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; @@ -1494,10 +1493,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-- +<?php include("skipif.inc"); ?> +--FILE-- +<?php +$val = []; +$var1 = $val; +printf("%x\n", count($val)); +@pg_pconnect($var1, "2", "3", "4"); +$var1 = ""; +tempnam('/tmp', 'ABCDEFGHI'); +printf("%x\n", count($val)); +?> +--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 |
