Bug #50373 --secure-file-priv=""
Submitted: 15 Jan 2010 15:30 Modified: 18 Jun 2010 1:07
Reporter: Sergei Golubchik Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.1, 5.5.99-m3 OS:Any
Assigned to: Kristofer Pettersson
Tags: Security
Triage: Triaged: D2 (Serious)

[15 Jan 2010 15:30] Sergei Golubchik
Description:
secure-file-priv cannot be reset on the command line, assigning an empty string does not work.

Besides, the fix for bug#43913 looks incorrect. opt_secure_file_priv is supposed to be normalized once, on startup, in mysqld.cc, fix_paths() function.
Not in sql_load.cc on every LOAD DATA, where it will not affect LOAD_FILE() function.

Of course, broken security related feature constitutes a security threat.

How to repeat:
mysqld --secure-file-priv="/foo" --secure-file-priv=""
[17 Jan 2010 7:29] Sveta Smirnova
Thank you for the report.

I can not repeat described behavior with current development sources.

$./libexec/mysqld --defaults-file=support-files/my-small.cnf --basedir=. --datadir=./data  --port=33051 --log-error --socket=/tmp/mysql_ssmirnova.sock  --secure-file-priv="/foo" --secure-file-priv="" &
[1] 19573

$./bin/mysql  --socket=/tmp/mysql_ssmirnova.sock -uroot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.44-debug Source distribution

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'secure%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_auth      | OFF   |
| secure_file_priv |       |
+------------------+-------+
2 rows in set (0.00 sec)

mysql> \q
Bye

Which exact version do you use?
[17 Jan 2010 9:07] Sergei Golubchik
I said that it doesn't work, not that it cannot be set to an empty string.
Doesn't work means that the protection is not lifted. The code in the fix for Bug#43913 looks like:

      else if (opt_secure_file_priv)
       {
        char secure_file_real_path[FN_REFLEN];
        (void) my_realpath(secure_file_real_path, opt_secure_file_priv, 0);
        if (strncmp(secure_file_real_path, name, strlen(secure_file_real_path)))

which only works when opt_secure_file_priv == 0. When it's an empty string, it will be expanded and normalized and compared. That means that an empty string does not disable the check.

The second bug in this bug fix: it only covers LOAD DATA. With --secure-file-priv="" we have

mysql> load data infile '/etc/group' into table t;
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

(which is incorrect, the as explained above), but

mysql> select load_file('/etc/group');
...
1 row in set (0.00 sec)

which shows that the opt_secure_file_priv works differently for LOAD_FILE() and LOAD DATA.
[17 Jan 2010 9:24] Sveta Smirnova
Thank you for the feedback.

Verified as described.
[14 Apr 2010 16:09] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/105657

3353 Kristofer Pettersson	2010-04-14
      Bug#50373 --secure-file-priv=""
      
      The server variable opt_secure_file_priv wasn't
      normalized properly and caused the operations
      LOAD DATA INFILE .. INTO TABLE ..
      and
      SELECT load_file(..)
      to do different interpretations of the 
      --secure-file-priv option.
      
      The patch moves code to the server initialization
      routines so that the path always is normalized
      once and only once.
      
      It was also intended that setting the option
      to an empty string should be equal to 
      lifting all previously set restrictions. This
      is also fixed by this patch.
     @ mysql-test/t/secure_file_priv-master.opt
        * added test case for bug 50737
     @ mysql-test/t/secure_file_priv.test
        * added test case for bug 50737
     @ sql/mysqld.cc
        * If --secure_file_option is an empty string then the option variable should be unset.
        * opt_secure_file_option should be normalized once when the server starts.
     @ sql/sql_load.cc
        * moved variable normalization code to fix_paths()
[16 Apr 2010 10:29] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/105842

3353 Kristofer Pettersson	2010-04-16
      Bug#50373 --secure-file-priv=""
      
      The server variable opt_secure_file_priv wasn't
      normalized properly and caused the operations
      LOAD DATA INFILE .. INTO TABLE ..
      and
      SELECT load_file(..)
      to do different interpretations of the 
      --secure-file-priv option.
      
      The patch moves code to the server initialization
      routines so that the path always is normalized
      once and only once.
      
      It was also intended that setting the option
      to an empty string should be equal to 
      lifting all previously set restrictions. This
      is also fixed by this patch.
     @ sql/mysqld.cc
        * If --secure_file_option is an empty string then the option variable
          should be unset.
        * opt_secure_file_option should be normalized once when the server starts.
     @ sql/sql_load.cc
        * moved variable normalization code to fix_paths()
[16 Apr 2010 14:11] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/105887

3352 Kristofer Pettersson	2010-04-16
      Bug#50373 --secure-file-priv=""
      
      The server variable opt_secure_file_priv wasn't
      normalized properly and caused the operations
      LOAD DATA INFILE .. INTO TABLE ..
      and
      SELECT load_file(..)
      to do different interpretations of the 
      --secure-file-priv option.
      
      The patch moves code to the server initialization
      routines so that the path always is normalized
      once and only once.
      
      It was also intended that setting the option
      to an empty string should be equal to 
      lifting all previously set restrictions. This
      is also fixed by this patch.
     @ sql/mysqld.cc
        * If --secure_file_option is an empty string then the option variable
          should be unset.
        * opt_secure_file_option should be normalized once when the server starts.
     @ sql/sql_load.cc
        * moved variable normalization code to fix_paths()
[20 Apr 2010 14:18] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/106109

3354 Kristofer Pettersson	2010-04-20
      Bug#50373 --secure-file-priv=""
      
      Correcting a patch misstake. The converted file path is placed in 'buff' not in opt_secure_file_priv.
     @ mysql-test/r/loaddata.result
        * Updated test case; Since secure_file_priv now is normalized the previous values are changed.
     @ sql/mysqld.cc
        * Fixed patch misstake
[3 May 2010 11:04] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/107176

3365 Kristofer Pettersson	2010-05-03
      Bug#50373 --secure-file-priv=""
      
      Iterative patch improvement. Previously committed patch
      caused wrong result on Windows. The previous patch also
      broke secure_file_priv for symlinks since not all file
      paths which must be compared against this variable are
      normalized using the same norm.
      
      The server variable opt_secure_file_priv wasn't
      normalized properly and caused the operations
      LOAD DATA INFILE .. INTO TABLE ..
      and
      SELECT load_file(..)
      to do different interpretations of the 
      --secure-file-priv option.
           
      The patch moves code to the server initialization
      routines so that the path always is normalized
      once and only once.
            
      It was also intended that setting the option
      to an empty string should be equal to 
      lifting all previously set restrictions. This
      is also fixed by this patch.
     @ mysql-test/r/loaddata.result
        * standard behavior for path normalization is to append a separator to the end of the file path.
     @ sql/item_strfunc.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
     @ sql/mysql_priv.h
        * Added signature for is_secure_file_path()
     @ sql/sql_class.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
     @ sql/sql_load.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
[3 May 2010 14:14] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/107201

3365 Kristofer Pettersson	2010-05-03
      Bug#50373 --secure-file-priv=""
      
      Iterative patch improvement. Previously committed patch
      caused wrong result on Windows. The previous patch also
      broke secure_file_priv for symlinks since not all file
      paths which must be compared against this variable are
      normalized using the same norm.
      
      The server variable opt_secure_file_priv wasn't
      normalized properly and caused the operations
      LOAD DATA INFILE .. INTO TABLE ..
      and
      SELECT load_file(..)
      to do different interpretations of the 
      --secure-file-priv option.
           
      The patch moves code to the server initialization
      routines so that the path always is normalized
      once and only once.
            
      It was also intended that setting the option
      to an empty string should be equal to 
      lifting all previously set restrictions. This
      is also fixed by this patch.
     @ mysql-test/r/loaddata.result
        * standard behavior for path normalization is to append a separator to the end of the file path.
     @ sql/item_strfunc.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
     @ sql/mysql_priv.h
        * Added signature for is_secure_file_path()
     @ sql/sql_class.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
     @ sql/sql_load.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
[3 May 2010 16:15] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/107217

3365 Kristofer Pettersson	2010-05-03
      Bug#50373 --secure-file-priv=""
      
      Iterative patch improvement. Previously committed patch
      caused wrong result on Windows. The previous patch also
      broke secure_file_priv for symlinks since not all file
      paths which must be compared against this variable are
      normalized using the same norm.
      
      The server variable opt_secure_file_priv wasn't
      normalized properly and caused the operations
      LOAD DATA INFILE .. INTO TABLE ..
      and
      SELECT load_file(..)
      to do different interpretations of the 
      --secure-file-priv option.
           
      The patch moves code to the server initialization
      routines so that the path always is normalized
      once and only once.
            
      It was also intended that setting the option
      to an empty string should be equal to 
      lifting all previously set restrictions. This
      is also fixed by this patch.
     @ mysql-test/r/loaddata.result
        * Removed test code which will currently break the much used --mem feature of mtr.
     @ mysql-test/t/loaddata.test
        * Removed test code which will currently break the much used --mem feature of mtr.
     @ sql/item_strfunc.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
     @ sql/mysql_priv.h
        * Added signature for is_secure_file_path()
     @ sql/mysqld.cc
        * New function for checking if a path compatible with the secure path restriction.
        * Added initialization of the opt_secure_file_priv variable.
     @ sql/sql_class.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
     @ sql/sql_load.cc
        * Replaced string comparing code on opt_secure_file_priv with an interface which guarantees that both file paths are normalized using the same norm on all platforms.
[5 May 2010 15:15] Bugs System
Pushed into 5.1.47 (revid:joro@sun.com-20100505145753-ivlt4hclbrjy8eye) (version source revid:kristofer.pettersson@sun.com-20100503161439-n4uisjixi4kpr9p7) (merge vers: 5.1.47) (pib:16)
[12 May 2010 10:43] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/108102

3021 Alexander Nozdrin	2010-05-12
      Post-fix for Bug#50373: sys_vars.secure_file_priv_basic can not be run
      with mysql-test/var as a symlink any longer.
[12 May 2010 11:14] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/108108

3022 Alexander Nozdrin	2010-05-12
      A follow-up for Bug#50373: remove a commented-out part of the loaddata.test.
[28 May 2010 6:07] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100524190136-egaq7e8zgkwb9aqi) (version source revid:alik@sun.com-20100512111424-3r8186eayf73xtdu) (pib:16)
[28 May 2010 6:35] Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20100524190941-nuudpx60if25wsvx) (version source revid:alik@sun.com-20100520134536-art1p9rrcytw602k) (merge vers: 6.0.14-alpha) (pib:16)
[28 May 2010 7:03] Bugs System
Pushed into 5.5.5-m3 (revid:alik@sun.com-20100524185725-c8k5q7v60i5nix3t) (version source revid:alik@sun.com-20100512111347-lek7yl2qepolmm5y) (merge vers: 5.5.5-m3) (pib:16)
[4 Jun 2010 1:53] Paul Dubois
Noted in 5.1.47, 5.5.5, 6.0.14 changelogs.

Setting --secure-file-priv to the empty string left the value
unaffected.
[17 Jun 2010 12:11] Bugs System
Pushed into 5.1.47-ndb-7.0.16 (revid:martin.skold@mysql.com-20100617114014-bva0dy24yyd67697) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 12:59] Bugs System
Pushed into 5.1.47-ndb-6.2.19 (revid:martin.skold@mysql.com-20100617115448-idrbic6gbki37h1c) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[17 Jun 2010 13:39] Bugs System
Pushed into 5.1.47-ndb-6.3.35 (revid:martin.skold@mysql.com-20100617114611-61aqbb52j752y116) (version source revid:vasil.dimov@oracle.com-20100331130613-8ja7n0vh36a80457) (merge vers: 5.1.46) (pib:16)
[29 Mar 2011 6:16] Magnus Blåudd
The testcase for this bug creates a file named bug50373.txt in the mysql-test directory, i.e outside of the designated var/ directory. This causes problem if that directory is readonly or in case the created file isn't properly removed, subsequent tests may fail.
[29 Mar 2011 6:19] Magnus Blåudd
Manually removing the bug50373.txt file and running

$>./mtr  sys_vars.secure_file_priv 
<snip>
sys_vars.secure_file_priv                [ fail ]
        Test ended at 2011-03-29 08:17:05

CURRENT_TEST: sys_vars.secure_file_priv
mysqltest: At line 19: command "remove_file" failed with error 1. my_errno=2

Then running again

$>./mtr  sys_vars.secure_file_priv 
<snip>
sys_vars.secure_file_priv                [ fail ]
        Test ended at 2011-03-29 08:18:41

CURRENT_TEST: sys_vars.secure_file_priv
mysqltest: At line 13: query 'SELECT * FROM t1 INTO OUTFILE '$PROTECTED_FILE';' failed: 1086: File '/home/msvensson/mysql/5.5-cluster/mysql-test/var/mysqld.1/data//../../../bug50373.txt' already exists