]> granicus.if.org Git - php/commitdiff
Fixed bug #72195 (pg_pconnect/pg_connect cause use-after-free)
authorXinchen Hui <laruence@gmail.com>
Thu, 12 May 2016 05:15:33 +0000 (13:15 +0800)
committerXinchen Hui <laruence@gmail.com>
Thu, 12 May 2016 05:15:33 +0000 (13:15 +0800)
NEWS
ext/pgsql/pgsql.c
ext/pgsql/tests/bug72195.phpt [new file with mode: 0644]
ext/pgsql/tests/config.inc

diff --git a/NEWS b/NEWS
index 1847b2d2c59c7b91489d829dbc99c8ea5f167bde..7472654778f8ec504ee2daf402ba5c124ecc356d 100644 (file)
--- 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)
index c196c97ee71b2b0ec81ff99c2f169e5959eed241..76dfd2a9e58af7aede72a0a3099fce99181f1559 100644 (file)
@@ -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 (file)
index 0000000..2f33e1a
--- /dev/null
@@ -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
index e9944de793cf34243f45fb30bb42fc13e35ea098..7be1e242ada488ec5b5893f598c56cdf6ef6525d 100644 (file)
@@ -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