]> granicus.if.org Git - php/commitdiff
Fixed bug #68077 (LOAD DATA LOCAL INFILE / open_basedir restriction)
authorXinchen Hui <laruence@gmail.com>
Mon, 16 Nov 2015 08:58:19 +0000 (16:58 +0800)
committerXinchen Hui <laruence@gmail.com>
Mon, 16 Nov 2015 08:59:55 +0000 (16:59 +0800)
Actually, this only be fixed if php uses mysqlnd

NEWS
ext/mysql/php_mysql.c
ext/mysqli/mysqli_api.c
ext/mysqli/mysqli_nonapi.c
ext/mysqli/tests/bug68077.phpt [new file with mode: 0644]
ext/mysqli/tests/mysqli_options_openbasedir.phpt
ext/mysqlnd/mysqlnd.c
ext/pdo_mysql/mysql_driver.c

diff --git a/NEWS b/NEWS
index a0b821f6fc68cff77ac66846ecbe28dfb5c14ebf..cb0b72fbe2e35132e1d3bbcf18e321e4a4212091 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2015, PHP 5.6.17
 
+- Mysqlnd:
+  . Fixed bug #68077 (LOAD DATA LOCAL INFILE / open_basedir restriction).
+    (Laruence)
+
 - SOAP:
   . Fixed bug #70900 (SoapClient systematic out of memory error). (Dmitry)
 
index 8a8a052bf51a0f3f1155e8d365467a0c9e585fe0..90ffb400b9406a353a12681b00aa094ff13010a6 100644 (file)
@@ -799,6 +799,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
                        passwd_len = passwd? strlen(passwd):0;
                }
 
+#if !defined(MYSQL_USE_MYSQLND)
                /* disable local infile option for open_basedir */
 #if PHP_API_VERSION < 20100412
                if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) {
@@ -807,6 +808,7 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
 #endif
                        client_flags ^= CLIENT_LOCAL_FILES;
                }
+#endif
 
 #ifdef CLIENT_MULTI_RESULTS
                client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */
index 72c029ebc861eba0af39c0e318e80e22915b4e37..47fcb9ecd5a6fd94d1882c579fe7d7e4808bea2c 100644 (file)
@@ -1824,6 +1824,7 @@ PHP_FUNCTION(mysqli_options)
        }
        MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_INITIALIZED);
 
+#if !defined(MYSQLI_USE_MYSQLND)
 #if PHP_API_VERSION < 20100412
        if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) {
 #else
@@ -1833,6 +1834,7 @@ PHP_FUNCTION(mysqli_options)
                        RETURN_FALSE;
                }
        }
+#endif
        expected_type = mysqli_options_get_option_zval_type(mysql_option);
        if (expected_type != Z_TYPE_PP(mysql_value)) {
                switch (expected_type) {
index 2ee6c9eee6eb85af468e0b0eda07c27fbc2ea8ff..859d1222fe1c03b476a5b94745e31704acfd6bd3 100644 (file)
@@ -120,9 +120,11 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
                flags |= CLIENT_MULTI_RESULTS; /* needed for mysql_multi_query() */
                /* remove some insecure options */
                flags &= ~CLIENT_MULTI_STATEMENTS;   /* don't allow multi_queries via connect parameter */
+#if !defined(MYSQLI_USE_MYSQLND)
                if (PG(open_basedir) && PG(open_basedir)[0] != '\0') {
                        flags &= ~CLIENT_LOCAL_FILES;
                }
+#endif
        }
 
        if (!socket_len || !socket) {
diff --git a/ext/mysqli/tests/bug68077.phpt b/ext/mysqli/tests/bug68077.phpt
new file mode 100644 (file)
index 0000000..18c2765
--- /dev/null
@@ -0,0 +1,70 @@
+--TEST--
+Bug #68077 (LOAD DATA LOCAL INFILE / open_basedir restriction)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifconnectfailure.inc');
+if (!$IS_MYSQLND) {
+       die("skip: test applies only to mysqlnd");
+}
+?>
+--INI--
+open_basedir={PWD}
+--FILE--
+<?php
+       require_once("connect.inc");
+
+       if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+               printf("[001] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+       }
+
+       if (!$link->query("DROP TABLE IF EXISTS test")) {
+               printf("[002] [%d] %s\n", $link->errno, $link->error);
+       }
+
+       if (!$link->query("CREATE TABLE test (dump1 INT UNSIGNED NOT NULL PRIMARY KEY) ENGINE=" . $engine)) {
+               printf("[003] [%d] %s\n", $link->errno, $link->error);
+       }
+
+       if (FALSE == file_put_contents(__DIR__ . '/bug53503.data', "1\n2\n3\n"))
+               printf("[004] Failed to create CVS file\n");
+
+       if (!$link->query("SELECT 1 FROM DUAL"))
+               printf("[005] [%d] %s\n", $link->errno, $link->error);
+
+       if (!$link->query("LOAD DATA LOCAL INFILE '" . __DIR__  . "/bug53503.data' INTO TABLE test")) {
+               printf("[006] [%d] %s\n", $link->errno, $link->error);
+               echo "bug\n";
+       } else {
+               echo "done\n";
+       }
+
+       if (!$link->query("LOAD DATA LOCAL INFILE '../../bug53503.data' INTO TABLE test")) {
+               printf("[006] [%d] %s\n", $link->errno, $link->error);
+               echo "done\n";
+       } else {
+               echo "bug\n";
+       }
+       $link->close();
+?>
+--CLEAN--
+<?php
+require_once('connect.inc');
+
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) {
+       printf("[clean] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+               $host, $user, $db, $port, $socket);
+}
+
+if (!$link->query($link, 'DROP TABLE IF EXISTS test')) {
+       printf("[clean] Failed to drop old test table: [%d] %s\n", mysqli_errno($link), mysqli_error($link));
+}
+
+$link->close();
+
+unlink('bug53503.data');
+?>
+--EXPECTF--
+done
+[006] [2000] open_basedir restriction in effect. Unable to open file
+done
index 4c13ec1ef013fb9409db69076497ea42cf3cff60..9457adfb5dfc21d1ceabee851d0d71af3088ea84 100644 (file)
@@ -8,16 +8,22 @@ require_once('skipifconnectfailure.inc');
 ?>
 --FILE--
 <?php
-       require_once('connect.inc');
-       ini_set("open_basedir", __DIR__);
-       if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
-               printf("[001] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
+require_once('connect.inc');
+ini_set("open_basedir", __DIR__);
+if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
+       printf("[001] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
 
+if ($IS_MYSQLND) {
+       if (true !== mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, 1))
+               printf("[002] Can not set MYSQLI_OPT_LOCAL_INFILE although open_basedir is set!\n");
+
+} else {
        if (false !== mysqli_options($link, MYSQLI_OPT_LOCAL_INFILE, 1))
                printf("[002] Can set MYSQLI_OPT_LOCAL_INFILE although open_basedir is set!\n");
 
-       mysqli_close($link);
-       print "done!";
+}
+mysqli_close($link);
+print "done!";
 ?>
 --EXPECTF--
 done!
index 94a314964d0c401ef7551ad6d2bf5caadcb1375e..5bdda605eaa24d495a6027d0e221ccc8c6e1d100 100644 (file)
@@ -759,10 +759,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA *
 
        mysql_flags |= conn->options->flags; /* use the flags from set_client_option() */
 
-       if (PG(open_basedir) && strlen(PG(open_basedir))) {
-               mysql_flags ^= CLIENT_LOCAL_FILES;
-       }
-
 #ifndef MYSQLND_COMPRESSION_ENABLED
        if (mysql_flags & CLIENT_COMPRESS) {
                mysql_flags &= ~CLIENT_COMPRESS;
index f1987531001d15aa8dc24e75a7f975097a96801d..7297c896bdce92a465b0ef35cab64ef9fe51992e 100644 (file)
@@ -629,6 +629,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
                        goto cleanup;
                }
 
+#ifndef PDO_USE_MYSQLND
 #if PHP_API_VERSION < 20100412
                if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode))
 #else
@@ -637,6 +638,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
                {
                        local_infile = 0;
                }
+#endif
 #if defined(MYSQL_OPT_LOCAL_INFILE) || defined(PDO_USE_MYSQLND)
                if (mysql_options(H->server, MYSQL_OPT_LOCAL_INFILE, (const char *)&local_infile)) {
                        pdo_mysql_error(dbh);