Loading mysql-test/r/symlink.result +21 −17 Original line number Diff line number Diff line Loading @@ -100,23 +100,15 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE t1(a INT) DATA DIRECTORY='TEST_DIR/master-data/mysql' INDEX DIRECTORY='TEST_DIR/master-data/mysql'; RENAME TABLE t1 TO user; ERROR HY000: Can't create/write to file 'TEST_DIR/master-data/mysql/user.MYI' (Errcode: 17) DROP TABLE t1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; DATA DIRECTORY='TEST_DIR/tmp' INDEX DIRECTORY='TEST_DIR/tmp'; ERROR HY000: Can't create/write to file 'TEST_DIR/tmp/t1.MYI' (Errcode: 17) CREATE TABLE t2(a INT) DATA DIRECTORY='TEST_DIR/tmp' INDEX DIRECTORY='TEST_DIR/tmp'; RENAME TABLE t2 TO t1; ERROR HY000: Can't create/write to file 'TEST_DIR/tmp/t1.MYI' (Errcode: 17) DROP TABLE t2; show create table t1; Table Create Table t1 CREATE TEMPORARY TABLE `t1` ( Loading @@ -138,6 +130,18 @@ select * from t1; a 42 drop table t1; CREATE TABLE t1(a INT) DATA DIRECTORY='TEST_DIR/var/master-data/test'; ERROR HY000: Incorrect arguments to DATA DIRECORY CREATE TABLE t1(a INT) DATA DIRECTORY='/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data/'; ERROR HY000: Incorrect arguments to DATA DIRECORY CREATE TABLE t1(a INT) INDEX DIRECTORY='/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data'; ERROR HY000: Incorrect arguments to INDEX DIRECORY CREATE TABLE t1(a INT) INDEX DIRECTORY='/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data_var'; ERROR HY000: Can't create/write to file '/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data_var/t1.MYI' (Errcode: 2) End of 4.1 tests CREATE DATABASE db1; CREATE DATABASE db2; Loading mysql-test/t/symlink.test +48 −19 Original line number Diff line number Diff line Loading @@ -127,29 +127,22 @@ drop table t1; # # BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE # --write_file $MYSQLTEST_VARDIR/tmp/t1.MYI EOF --replace_result $MYSQLTEST_VARDIR TEST_DIR --error 1 eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql' INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql'; DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp'; --replace_result $MYSQLTEST_VARDIR TEST_DIR eval CREATE TABLE t2(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp'; --replace_result $MYSQLTEST_VARDIR TEST_DIR --error 1 RENAME TABLE t1 TO user; DROP TABLE t1; # # Test specifying DATA DIRECTORY that is the same as what would normally # have been chosen. (Bug #8707) # disable_query_log; eval create table t1 (i int) data directory = "$MYSQLTEST_VARDIR/master-data/test/"; enable_query_log; show create table t1; drop table t1; disable_query_log; eval create table t1 (i int) index directory = "$MYSQLTEST_VARDIR/master-data/test/"; enable_query_log; show create table t1; drop table t1; RENAME TABLE t2 TO t1; DROP TABLE t2; --remove_file $MYSQLTEST_VARDIR/tmp/t1.MYI # # Bug#8706 - temporary table with data directory option fails Loading Loading @@ -188,6 +181,42 @@ connection default; select * from t1; drop table t1; # # CREATE TABLE with DATA DIRECTORY option # # Protect ourselves from data left in tmp/ by a previos possibly failed # test --system rm -f $MYSQLTEST_VARDIR/tmp/t1.* --disable_query_log eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'"; --enable_query_log execute stmt; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR show create table t1; drop table t1; execute stmt; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR show create table t1; drop table t1; deallocate prepare stmt; # # Bug#32167 another privilege bypass with DATA/INDEX DIRECORY # --replace_result $MYSQL_TEST_DIR TEST_DIR --error 1210 eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/test'; --error 1210 eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/'; --error 1210 eval CREATE TABLE t1(a INT) INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data'; --error 1 eval CREATE TABLE t1(a INT) INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data_var'; --echo End of 4.1 tests # Loading sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -1255,6 +1255,7 @@ void my_dbopt_free(void); extern time_t server_start_time; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[], mysql_unpacked_real_data_home[], def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; #define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) extern MY_TMPDIR mysql_tmpdir_list; Loading sql/mysqld.cc +9 −1 Original line number Diff line number Diff line Loading @@ -474,7 +474,12 @@ key_map key_map_full(0); // Will be initialized later const char *opt_date_time_formats[3]; char *mysql_data_home= mysql_real_data_home; char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; char *language_ptr, *default_collation_name, *default_character_set_name; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char mysql_unpacked_real_data_home[FN_REFLEN]; struct passwd *user_info; char server_version[SERVER_VERSION_LENGTH]; char *mysqld_unix_port, *opt_mysql_tmpdir; const char **errmesg; /* Error messages */ Loading Loading @@ -7609,6 +7614,9 @@ static void fix_paths(void) pos[1]= 0; } convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); (void) fn_format(buff, mysql_real_data_home, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); (void) unpack_dirname(mysql_unpacked_real_data_home, buff); convert_dirname(language,language,NullS); (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); Loading sql/sql_parse.cc +62 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ static void remove_escape(char *name); static bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); static TABLE_LIST* get_table_by_alias(TABLE_LIST* tl, const char* db, const char* alias); static bool test_if_data_home_dir(const char *dir); const char *any_db="*any*"; // Special symbol for check_access Loading Loading @@ -3055,6 +3058,20 @@ mysql_execute_command(THD *thd) "INDEX DIRECTORY option ignored"); create_info.data_file_name= create_info.index_file_name= NULL; #else if (test_if_data_home_dir(lex->create_info.data_file_name)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY"); res= -1; break; } if (test_if_data_home_dir(lex->create_info.index_file_name)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY"); res= -1; break; } /* Fix names if symlinked tables */ if (append_file_to_dir(thd, &create_info.data_file_name, create_table->table_name) || Loading Loading @@ -7898,3 +7915,48 @@ bool check_string_length(LEX_STRING *str, const char *err_msg, return TRUE; } /* Check if path does not contain mysql data home directory SYNOPSIS test_if_data_home_dir() dir directory conv_home_dir converted data home directory home_dir_len converted data home directory length RETURN VALUES 0 ok 1 error */ static bool test_if_data_home_dir(const char *dir) { char path[FN_REFLEN], conv_path[FN_REFLEN]; uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home); DBUG_ENTER("test_if_data_home_dir"); if (!dir) DBUG_RETURN(0); (void) fn_format(path, dir, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); dir_len= unpack_dirname(conv_path, dir); if (home_dir_len <= dir_len) { if (lower_case_file_system) { if (!my_strnncoll(default_charset_info, (const uchar*) conv_path, home_dir_len, (const uchar*) mysql_unpacked_real_data_home, home_dir_len)) DBUG_RETURN(1); } else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len)) DBUG_RETURN(1); } DBUG_RETURN(0); } Loading
mysql-test/r/symlink.result +21 −17 Original line number Diff line number Diff line Loading @@ -100,23 +100,15 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; CREATE TABLE t1(a INT) DATA DIRECTORY='TEST_DIR/master-data/mysql' INDEX DIRECTORY='TEST_DIR/master-data/mysql'; RENAME TABLE t1 TO user; ERROR HY000: Can't create/write to file 'TEST_DIR/master-data/mysql/user.MYI' (Errcode: 17) DROP TABLE t1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; DATA DIRECTORY='TEST_DIR/tmp' INDEX DIRECTORY='TEST_DIR/tmp'; ERROR HY000: Can't create/write to file 'TEST_DIR/tmp/t1.MYI' (Errcode: 17) CREATE TABLE t2(a INT) DATA DIRECTORY='TEST_DIR/tmp' INDEX DIRECTORY='TEST_DIR/tmp'; RENAME TABLE t2 TO t1; ERROR HY000: Can't create/write to file 'TEST_DIR/tmp/t1.MYI' (Errcode: 17) DROP TABLE t2; show create table t1; Table Create Table t1 CREATE TEMPORARY TABLE `t1` ( Loading @@ -138,6 +130,18 @@ select * from t1; a 42 drop table t1; CREATE TABLE t1(a INT) DATA DIRECTORY='TEST_DIR/var/master-data/test'; ERROR HY000: Incorrect arguments to DATA DIRECORY CREATE TABLE t1(a INT) DATA DIRECTORY='/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data/'; ERROR HY000: Incorrect arguments to DATA DIRECORY CREATE TABLE t1(a INT) INDEX DIRECTORY='/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data'; ERROR HY000: Incorrect arguments to INDEX DIRECORY CREATE TABLE t1(a INT) INDEX DIRECTORY='/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data_var'; ERROR HY000: Can't create/write to file '/home/gluh/MySQL/Merge/4.1-opt/mysql-test/var/master-data_var/t1.MYI' (Errcode: 2) End of 4.1 tests CREATE DATABASE db1; CREATE DATABASE db2; Loading
mysql-test/t/symlink.test +48 −19 Original line number Diff line number Diff line Loading @@ -127,29 +127,22 @@ drop table t1; # # BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE # --write_file $MYSQLTEST_VARDIR/tmp/t1.MYI EOF --replace_result $MYSQLTEST_VARDIR TEST_DIR --error 1 eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql' INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql'; DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp'; --replace_result $MYSQLTEST_VARDIR TEST_DIR eval CREATE TABLE t2(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY='$MYSQLTEST_VARDIR/tmp'; --replace_result $MYSQLTEST_VARDIR TEST_DIR --error 1 RENAME TABLE t1 TO user; DROP TABLE t1; # # Test specifying DATA DIRECTORY that is the same as what would normally # have been chosen. (Bug #8707) # disable_query_log; eval create table t1 (i int) data directory = "$MYSQLTEST_VARDIR/master-data/test/"; enable_query_log; show create table t1; drop table t1; disable_query_log; eval create table t1 (i int) index directory = "$MYSQLTEST_VARDIR/master-data/test/"; enable_query_log; show create table t1; drop table t1; RENAME TABLE t2 TO t1; DROP TABLE t2; --remove_file $MYSQLTEST_VARDIR/tmp/t1.MYI # # Bug#8706 - temporary table with data directory option fails Loading Loading @@ -188,6 +181,42 @@ connection default; select * from t1; drop table t1; # # CREATE TABLE with DATA DIRECTORY option # # Protect ourselves from data left in tmp/ by a previos possibly failed # test --system rm -f $MYSQLTEST_VARDIR/tmp/t1.* --disable_query_log eval prepare stmt from "create table t1 (c char(10)) data directory='$MYSQLTEST_VARDIR/tmp'"; --enable_query_log execute stmt; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR show create table t1; drop table t1; execute stmt; --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR show create table t1; drop table t1; deallocate prepare stmt; # # Bug#32167 another privilege bypass with DATA/INDEX DIRECORY # --replace_result $MYSQL_TEST_DIR TEST_DIR --error 1210 eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/test'; --error 1210 eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/'; --error 1210 eval CREATE TABLE t1(a INT) INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data'; --error 1 eval CREATE TABLE t1(a INT) INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data_var'; --echo End of 4.1 tests # Loading
sql/mysql_priv.h +1 −0 Original line number Diff line number Diff line Loading @@ -1255,6 +1255,7 @@ void my_dbopt_free(void); extern time_t server_start_time; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[], mysql_unpacked_real_data_home[], def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; #define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) extern MY_TMPDIR mysql_tmpdir_list; Loading
sql/mysqld.cc +9 −1 Original line number Diff line number Diff line Loading @@ -474,7 +474,12 @@ key_map key_map_full(0); // Will be initialized later const char *opt_date_time_formats[3]; char *mysql_data_home= mysql_real_data_home; char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME; char *language_ptr, *default_collation_name, *default_character_set_name; char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home; char mysql_unpacked_real_data_home[FN_REFLEN]; struct passwd *user_info; char server_version[SERVER_VERSION_LENGTH]; char *mysqld_unix_port, *opt_mysql_tmpdir; const char **errmesg; /* Error messages */ Loading Loading @@ -7609,6 +7614,9 @@ static void fix_paths(void) pos[1]= 0; } convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); (void) fn_format(buff, mysql_real_data_home, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); (void) unpack_dirname(mysql_unpacked_real_data_home, buff); convert_dirname(language,language,NullS); (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); Loading
sql/sql_parse.cc +62 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,9 @@ static void remove_escape(char *name); static bool append_file_to_dir(THD *thd, const char **filename_ptr, const char *table_name); static bool check_show_create_table_access(THD *thd, TABLE_LIST *table); static TABLE_LIST* get_table_by_alias(TABLE_LIST* tl, const char* db, const char* alias); static bool test_if_data_home_dir(const char *dir); const char *any_db="*any*"; // Special symbol for check_access Loading Loading @@ -3055,6 +3058,20 @@ mysql_execute_command(THD *thd) "INDEX DIRECTORY option ignored"); create_info.data_file_name= create_info.index_file_name= NULL; #else if (test_if_data_home_dir(lex->create_info.data_file_name)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY"); res= -1; break; } if (test_if_data_home_dir(lex->create_info.index_file_name)) { my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY"); res= -1; break; } /* Fix names if symlinked tables */ if (append_file_to_dir(thd, &create_info.data_file_name, create_table->table_name) || Loading Loading @@ -7898,3 +7915,48 @@ bool check_string_length(LEX_STRING *str, const char *err_msg, return TRUE; } /* Check if path does not contain mysql data home directory SYNOPSIS test_if_data_home_dir() dir directory conv_home_dir converted data home directory home_dir_len converted data home directory length RETURN VALUES 0 ok 1 error */ static bool test_if_data_home_dir(const char *dir) { char path[FN_REFLEN], conv_path[FN_REFLEN]; uint dir_len, home_dir_len= strlen(mysql_unpacked_real_data_home); DBUG_ENTER("test_if_data_home_dir"); if (!dir) DBUG_RETURN(0); (void) fn_format(path, dir, "", "", (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS)); dir_len= unpack_dirname(conv_path, dir); if (home_dir_len <= dir_len) { if (lower_case_file_system) { if (!my_strnncoll(default_charset_info, (const uchar*) conv_path, home_dir_len, (const uchar*) mysql_unpacked_real_data_home, home_dir_len)) DBUG_RETURN(1); } else if (!memcmp(conv_path, mysql_unpacked_real_data_home, home_dir_len)) DBUG_RETURN(1); } DBUG_RETURN(0); }