From 59d7516005af28dce97c3f4251e2d7da2e31d203 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 28 Apr 2011 12:22:41 +0300 Subject: Bug #11764517: 57359: POSSIBLE TO CIRCUMVENT SECURE_FILE_PRIV USING '..' ON WINDOWS Backport of the fix to 5.0 (to be null-merged to 5.1). Moved the test into the main test suite. Made mysql-test-run.pl to not use symlinks for sdtdata as the symlinks are now properly recognized by secure_file_priv. Made sure the paths in load_file(), LOAD DATA and SELECT .. INTO OUTFILE that are checked against secure_file_priv in a correct way similarly to 5.1 by the extended is_secure_file_path() backport before the comparison. Added an extensive test with all the variants of upper/lower case, slash/backslash and case sensitivity. Added few comments to the code. --- sql/sql_load.cc | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'sql/sql_load.cc') diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 83af6d477db..9cead8c0ff1 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -287,36 +287,36 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { (void) fn_format(name, ex->file_name, mysql_real_data_home, "", MY_RELATIVE_PATH | MY_UNPACK_FILENAME); + } + + if (!is_secure_file_path(name)) + { + /* Read only allowed from within dir specified by secure_file_priv */ + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); + DBUG_RETURN(TRUE); + } + #if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__) - MY_STAT stat_info; - if (!my_stat(name,&stat_info,MYF(MY_WME))) - DBUG_RETURN(TRUE); + MY_STAT stat_info; + if (!my_stat(name, &stat_info, MYF(MY_WME))) + DBUG_RETURN(TRUE); - // if we are not in slave thread, the file must be: - if (!thd->slave_thread && - !((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others + // if we are not in slave thread, the file must be: + if (!thd->slave_thread && + !((stat_info.st_mode & S_IROTH) == S_IROTH && // readable by others #ifndef __EMX__ - (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink + (stat_info.st_mode & S_IFLNK) != S_IFLNK && // and not a symlink #endif - ((stat_info.st_mode & S_IFREG) == S_IFREG || - (stat_info.st_mode & S_IFIFO) == S_IFIFO))) - { - my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name); - DBUG_RETURN(TRUE); - } - if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) - is_fifo = 1; + ((stat_info.st_mode & S_IFREG) == S_IFREG || // and a regular file + (stat_info.st_mode & S_IFIFO) == S_IFIFO))) // or FIFO + { + my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), name); + DBUG_RETURN(TRUE); + } + if ((stat_info.st_mode & S_IFIFO) == S_IFIFO) + is_fifo= 1; #endif - if (opt_secure_file_priv && - strncmp(opt_secure_file_priv, name, strlen(opt_secure_file_priv))) - { - /* Read only allowed from within dir specified by secure_file_priv */ - my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--secure-file-priv"); - DBUG_RETURN(TRUE); - } - - } if ((file=my_open(name,O_RDONLY,MYF(MY_WME))) < 0) DBUG_RETURN(TRUE); } -- cgit v1.2.1