summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2016-05-12 13:15:33 +0800
committerXinchen Hui <laruence@gmail.com>2016-05-12 13:15:33 +0800
commit3c0341e6f9c802ff50cc4eb08e6b90793d033aad (patch)
treeb269125d9901cfeeccf9e297fb5a43aaee4d4137
parentdf404e2e0eb190cd40f8f04a237cb9b655022148 (diff)
downloadphp-git-3c0341e6f9c802ff50cc4eb08e6b90793d033aad.tar.gz
Fixed bug #72195 (pg_pconnect/pg_connect cause use-after-free)
-rw-r--r--NEWS3
-rw-r--r--ext/pgsql/pgsql.c15
-rw-r--r--ext/pgsql/tests/bug72195.phpt17
-rw-r--r--ext/pgsql/tests/config.inc2
4 files changed, 32 insertions, 5 deletions
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--
+<?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