diff options
-rw-r--r-- | mysql-test/r/partition.result | 28 | ||||
-rw-r--r-- | mysql-test/r/partition_not_windows.result | 6 | ||||
-rw-r--r-- | mysql-test/r/partition_symlink.result | 32 | ||||
-rw-r--r-- | mysql-test/r/symlink.result | 65 | ||||
-rw-r--r-- | mysql-test/t/partition.test | 42 | ||||
-rw-r--r-- | mysql-test/t/partition_not_windows.test | 32 | ||||
-rw-r--r-- | mysql-test/t/partition_symlink.test | 40 | ||||
-rw-r--r-- | mysql-test/t/symlink.test | 94 | ||||
-rw-r--r-- | sql/mysql_priv.h | 4 | ||||
-rw-r--r-- | sql/mysqld.cc | 4 | ||||
-rw-r--r-- | sql/partition_info.cc | 56 | ||||
-rw-r--r-- | sql/partition_info.h | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 65 |
13 files changed, 325 insertions, 144 deletions
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index a361a8f6bcc..be3c68e6c18 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1320,6 +1320,34 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXTENDED' at line 1 DROP TABLE t1; +CREATE TABLE t1(a INT) +PARTITION BY KEY (a) +(PARTITION p0 DATA DIRECTORY 'TEST_DIR/master-data/test'); +ERROR HY000: Incorrect arguments to DATA DIRECORY +CREATE TABLE t1(a INT) +PARTITION BY KEY (a) +(PARTITION p0 INDEX DIRECTORY 'TEST_DIR/master-data/test'); +ERROR HY000: Incorrect arguments to INDEX DIRECORY +CREATE TABLE ts (id INT, purchased DATE) +PARTITION BY RANGE(YEAR(purchased)) +SUBPARTITION BY HASH(TO_DAYS(purchased)) ( +PARTITION p0 VALUES LESS THAN (1990) ( +SUBPARTITION s0a +DATA DIRECTORY = 'TEST_DIR/master-data/test', +SUBPARTITION s0b +DATA DIRECTORY = 'TEST_DIR/master-data/test' +)); +ERROR HY000: Incorrect arguments to DATA DIRECORY +CREATE TABLE ts (id INT, purchased DATE) +PARTITION BY RANGE(YEAR(purchased)) +SUBPARTITION BY HASH(TO_DAYS(purchased)) ( +PARTITION p0 VALUES LESS THAN (1990) ( +SUBPARTITION s0a +INDEX DIRECTORY = 'TEST_DIR/master-data/test', +SUBPARTITION s0b +INDEX DIRECTORY = 'TEST_DIR/master-data/test' +)); +ERROR HY000: Incorrect arguments to INDEX DIRECORY CREATE TABLE t1 (s1 BIGINT UNSIGNED) PARTITION BY RANGE (s1) ( PARTITION p0 VALUES LESS THAN (0), diff --git a/mysql-test/r/partition_not_windows.result b/mysql-test/r/partition_not_windows.result index 31ea300e8ed..af36673a3e0 100644 --- a/mysql-test/r/partition_not_windows.result +++ b/mysql-test/r/partition_not_windows.result @@ -1,13 +1,13 @@ create table t1 (a int) engine myisam partition by range (a) subpartition by hash (a) -(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx' +(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp' (SUBPARTITION subpart00, SUBPARTITION subpart01)); Checking if file exists before alter ALTER TABLE t1 REORGANIZE PARTITION p0 INTO -(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx' +(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp' (SUBPARTITION subpart10, SUBPARTITION subpart11), -partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx' +partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'MYSQLTEST_VARDIR/tmp' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/tmp' (SUBPARTITION subpart20, SUBPARTITION subpart21)); Checking if file exists after alter drop table t1; diff --git a/mysql-test/r/partition_symlink.result b/mysql-test/r/partition_symlink.result index 20e841d2e0e..362e97a6262 100644 --- a/mysql-test/r/partition_symlink.result +++ b/mysql-test/r/partition_symlink.result @@ -13,11 +13,11 @@ USE test; CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2', +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test', +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp', PARTITION p2 VALUES IN (2) ); # without the patch for bug#32091 this would create @@ -49,32 +49,32 @@ USE mysqltest2; CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2', +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp' ); # user mysqltest_1: USE test; CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2', +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp' ); Got one of the listed errors CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/test', +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) -DATA DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY 'MYSQLTEST_VARDIR/master-data/mysqltest2' +DATA DIRECTORY 'MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY 'MYSQLTEST_VARDIR/tmp' ); Got one of the listed errors # user root (cleanup): diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 4eece9d5b5a..e4ae1d8ea28 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -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` ( @@ -139,26 +131,25 @@ a 42 drop table t1; End of 4.1 tests -CREATE DATABASE db1; -CREATE DATABASE db2; -USE db2; -INSERT INTO db2.t1 VALUES (1); -SELECT * FROM db2.t1; -b -1 -RESET QUERY CACHE; -USE db1; SET SESSION keep_files_on_create = TRUE; CREATE TABLE t1 (a INT) ENGINE MYISAM; -Got one of the listed errors -CREATE TABLE t3 (a INT) Engine=MyISAM; -INSERT INTO t3 VALUES (1),(2),(3); -TRUNCATE TABLE t3; -SELECT * from t3; -a -SET SESSION keep_files_on_create = DEFAULT; -DROP TABLE db2.t1, db1.t3; -DROP DATABASE db1; -DROP DATABASE db2; -USE test; +ERROR HY000: Can't create/write to file './test/t1.MYD' (Errcode: 17) +SET SESSION keep_files_on_create = FALSE; +CREATE TABLE t1 (a INT) ENGINE MYISAM; +DROP TABLE t1; End of 5.0 tests +CREATE TABLE t1(a INT) +INDEX DIRECTORY='TEST_DIR/master-data/mysql'; +ERROR HY000: Incorrect arguments to INDEX DIRECORY +CREATE TABLE t1(a INT) +DATA DIRECTORY='TEST_DIR/master-data/test'; +ERROR HY000: Incorrect arguments to DATA DIRECORY +CREATE TABLE t1(a INT) +DATA DIRECTORY='TEST_DIR/master-data/'; +DROP TABLE t1; +CREATE TABLE t1(a INT) +INDEX DIRECTORY='TEST_DIR/master-data'; +DROP TABLE t1; +CREATE TABLE t1(a INT) +INDEX DIRECTORY='TEST_DIR/master-data_var'; +ERROR HY000: Can't create/write to file 'TEST_DIR/master-data_var/t1.MYI' (Errcode: 2) diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 23d6c5f8865..d889fe83dc1 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1407,8 +1407,8 @@ eval create table t2 (i int ) partition by range (i) ( partition p01 values less than (1000) - data directory="$MYSQLTEST_VARDIR/master-data/test/" - index directory="$MYSQLTEST_VARDIR/master-data/test/" + data directory="$MYSQLTEST_VARDIR/tmp/" + index directory="$MYSQLTEST_VARDIR/tmp/" ); enable_query_log; @@ -1575,6 +1575,44 @@ ALTER TABLE t1 ANALYZE PARTITION p1 EXTENDED; DROP TABLE t1; # +# Bug#32167: another privilege bypass with DATA/INDEX DIRECTORY +# +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1210 +eval CREATE TABLE t1(a INT) +PARTITION BY KEY (a) +(PARTITION p0 DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test'); +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1210 +eval CREATE TABLE t1(a INT) +PARTITION BY KEY (a) +(PARTITION p0 INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test'); + +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1210 +eval CREATE TABLE ts (id INT, purchased DATE) +PARTITION BY RANGE(YEAR(purchased)) +SUBPARTITION BY HASH(TO_DAYS(purchased)) ( +PARTITION p0 VALUES LESS THAN (1990) ( +SUBPARTITION s0a + DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/test', +SUBPARTITION s0b + DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/test' +)); + +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1210 +eval CREATE TABLE ts (id INT, purchased DATE) +PARTITION BY RANGE(YEAR(purchased)) +SUBPARTITION BY HASH(TO_DAYS(purchased)) ( +PARTITION p0 VALUES LESS THAN (1990) ( +SUBPARTITION s0a + INDEX DIRECTORY = '$MYSQLTEST_VARDIR/master-data/test', +SUBPARTITION s0b + INDEX DIRECTORY = '$MYSQLTEST_VARDIR/master-data/test' +)); + +# # Bug #29258: Partitions: search fails for maximum unsigned bigint # CREATE TABLE t1 (s1 BIGINT UNSIGNED) diff --git a/mysql-test/t/partition_not_windows.test b/mysql-test/t/partition_not_windows.test index 012b8b50dee..c5f54286095 100644 --- a/mysql-test/t/partition_not_windows.test +++ b/mysql-test/t/partition_not_windows.test @@ -12,12 +12,10 @@ # doesn't remove old directory --disable_query_log ---exec mkdir $MYSQLTEST_VARDIR/master-data/tmpdata || true -eval SET @data_dir = 'DATA DIRECTORY = ''$MYSQLTEST_VARDIR/master-data/tmpdata'''; +eval SET @data_dir = 'DATA DIRECTORY = ''$MYSQLTEST_VARDIR/tmp'''; let $data_directory = `select @data_dir`; ---exec mkdir $MYSQLTEST_VARDIR/master-data/tmpinx || true -eval SET @inx_dir = 'INDEX DIRECTORY = ''$MYSQLTEST_VARDIR/master-data/tmpinx'''; +eval SET @inx_dir = 'INDEX DIRECTORY = ''$MYSQLTEST_VARDIR/tmp'''; let $inx_directory = `select @inx_dir`; --enable_query_log @@ -35,10 +33,10 @@ subpartition by hash (a) --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYI --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYD --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYI ---file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD ---file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD ---file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI ---file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p0#SP#subpart00.MYD +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p0#SP#subpart01.MYD +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p0#SP#subpart00.MYI +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p0#SP#subpart01.MYI --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval ALTER TABLE t1 REORGANIZE PARTITION p0 INTO @@ -58,18 +56,16 @@ eval ALTER TABLE t1 REORGANIZE PARTITION p0 INTO --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYI --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYD --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYI ---file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD ---file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD ---file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD ---file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD ---file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI ---file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI ---file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI ---file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p1#SP#subpart10.MYD +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p1#SP#subpart11.MYD +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p2#SP#subpart20.MYD +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p2#SP#subpart21.MYD +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p1#SP#subpart10.MYI +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p1#SP#subpart11.MYI +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p2#SP#subpart20.MYI +--file_exists $MYSQLTEST_VARDIR/tmp/t1#P#p2#SP#subpart21.MYI drop table t1; ---exec rmdir $MYSQLTEST_VARDIR/master-data/tmpdata || true ---exec rmdir $MYSQLTEST_VARDIR/master-data/tmpinx || true # End Windows specific test failures. diff --git a/mysql-test/t/partition_symlink.test b/mysql-test/t/partition_symlink.test index ab779ec2b68..4c6acec64eb 100644 --- a/mysql-test/t/partition_symlink.test +++ b/mysql-test/t/partition_symlink.test @@ -24,6 +24,10 @@ DROP DATABASE IF EXISTS mysqltest2; # files, but not the other way around (any db-user can use any # directory or file that the mysqld-process can use, via DATA/INDEX DIR) # this is the security flaw that was used in bug#32091 and bug#32111 + +#--exec mkdir $MYSQLTEST_VARDIR/tmp/test || true +#--exec mkdir $MYSQLTEST_VARDIR/tmp/mysqltest2 || true + -- echo # Creating two non colliding tables mysqltest2.t1 and test.t1 -- echo # test.t1 have partitions in mysqltest2-directory! -- echo # user root: @@ -39,11 +43,11 @@ connect(con1,localhost,mysqltest_1,,); eval CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2', + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test', + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp', PARTITION p2 VALUES IN (2) ); -- echo # without the patch for bug#32091 this would create @@ -74,17 +78,18 @@ connection default; # So it is using/blocking 2 files in (in 2 different directories -- echo # test that symlinks can not overwrite files when CREATE TABLE -- echo # user root: + CREATE DATABASE mysqltest2; USE mysqltest2; -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2', + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp' ); connection con1; -- echo # user mysqltest_1: @@ -94,22 +99,22 @@ connection con1; eval CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2', + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp' ); -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -- error 1,1 eval CREATE TABLE t1 (a INT) PARTITION BY LIST (a) ( PARTITION p0 VALUES IN (0) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/test' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/test', + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp', PARTITION p1 VALUES IN (1) - DATA DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' - INDEX DIRECTORY '$MYSQLTEST_VARDIR/master-data/mysqltest2' + DATA DIRECTORY '$MYSQLTEST_VARDIR/tmp' + INDEX DIRECTORY '$MYSQLTEST_VARDIR/tmp' ); connection default; -- echo # user root (cleanup): @@ -118,4 +123,5 @@ connection default; DROP USER mysqltest_1@localhost; disconnect con1; - +#--exec rmdir $MYSQLTEST_VARDIR/tmp/test || true +#--exec rmdir $MYSQLTEST_VARDIR/tmp/mysqltest2 || true diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index f339b29c83a..1b75fa6b1ab 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -123,29 +123,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 @@ -189,40 +182,41 @@ drop table t1; # # Bug #29325: create table overwrites .MYD file of other table (datadir) # - -CREATE DATABASE db1; -CREATE DATABASE db2; - -USE db2; ---disable_query_log -eval CREATE TABLE t1 (b INT) ENGINE MYISAM -DATA DIRECTORY = '$MYSQLTEST_VARDIR/master-data/db1/'; ---enable_query_log - -INSERT INTO db2.t1 VALUES (1); -SELECT * FROM db2.t1; -RESET QUERY CACHE; - -USE db1; - -#no warning from create table SET SESSION keep_files_on_create = TRUE; +--write_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD +EOF --disable_abort_on_error ---error 1,1 +--error 1 CREATE TABLE t1 (a INT) ENGINE MYISAM; +--error 0,1 +--remove_file $MYSQLTEST_VARDIR/master-data/test/t1.MYD; --enable_abort_on_error - -CREATE TABLE t3 (a INT) Engine=MyISAM; -INSERT INTO t3 VALUES (1),(2),(3); -TRUNCATE TABLE t3; -SELECT * from t3; - -SET SESSION keep_files_on_create = DEFAULT; - -DROP TABLE db2.t1, db1.t3; -DROP DATABASE db1; -DROP DATABASE db2; -USE test; - +SET SESSION keep_files_on_create = FALSE; +CREATE TABLE t1 (a INT) ENGINE MYISAM; +DROP TABLE t1; --echo End of 5.0 tests + +# +# Bug#32167: another privilege bypass with DATA/INDEX DIRECTORY +# +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1210 +eval CREATE TABLE t1(a INT) +INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql'; +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1210 +eval CREATE TABLE t1(a INT) +DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/test'; +--replace_result $MYSQLTEST_VARDIR TEST_DIR +eval CREATE TABLE t1(a INT) +DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/'; +DROP TABLE t1; +--replace_result $MYSQLTEST_VARDIR TEST_DIR +eval CREATE TABLE t1(a INT) +INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data'; +DROP TABLE t1; +--replace_result $MYSQLTEST_VARDIR TEST_DIR +--error 1 +eval CREATE TABLE t1(a INT) +INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data_var'; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ea552414d9a..ea5e03489ba 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -748,6 +748,7 @@ bool check_string_byte_length(LEX_STRING *str, const char *err_msg, bool check_string_char_length(LEX_STRING *str, const char *err_msg, uint max_char_length, CHARSET_INFO *cs, bool no_error); +bool test_if_data_home_dir(const char *dir); bool parse_sql(THD *thd, class Lex_input_stream *lip, @@ -1789,7 +1790,8 @@ extern time_t server_start_time, flush_status_time; #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS extern uint mysql_data_home_len; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], - mysql_real_data_home[]; + mysql_real_data_home[], mysql_unpacked_real_data_home[]; +extern CHARSET_INFO *character_set_filesystem; #endif /* MYSQL_SERVER || INNODB_COMPATIBILITY_HOOKS */ #ifdef MYSQL_SERVER extern char *opt_mysql_tmpdir, mysql_charsets_dir[], diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6dc63012f55..a62d0afee86 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -510,6 +510,7 @@ char mysql_real_data_home[FN_REFLEN], language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], *opt_init_file, *opt_tc_log_file, def_ft_boolean_syntax[sizeof(ft_boolean_syntax)]; +char mysql_unpacked_real_data_home[FN_REFLEN]; uint reg_ext_length; const key_map key_map_empty(0); key_map key_map_full(0); // Will be initialized later @@ -8147,6 +8148,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); diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 3b580422da1..3130f84bd73 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -1047,4 +1047,60 @@ error: mem_alloc_error(size); DBUG_RETURN(TRUE); } + + +/* + Check if path does not contain mysql data home directory + for partition elements with data directory and index directory + + SYNOPSIS + check_partition_dirs() + part_info partition_info struct + + RETURN VALUES + 0 ok + 1 error +*/ + +bool check_partition_dirs(partition_info *part_info) +{ + if (!part_info) + return 0; + + partition_element *part_elem; + List_iterator<partition_element> part_it(part_info->partitions); + while ((part_elem= part_it++)) + { + if (part_elem->subpartitions.elements) + { + List_iterator<partition_element> sub_it(part_elem->subpartitions); + partition_element *subpart_elem; + while ((subpart_elem= sub_it++)) + { + if (test_if_data_home_dir(subpart_elem->data_file_name)) + goto dd_err; + if (test_if_data_home_dir(subpart_elem->index_file_name)) + goto id_err; + } + } + else + { + if (test_if_data_home_dir(part_elem->data_file_name)) + goto dd_err; + if (test_if_data_home_dir(part_elem->index_file_name)) + goto id_err; + } + } + return 0; + +dd_err: + my_error(ER_WRONG_ARGUMENTS,MYF(0),"DATA DIRECORY"); + return 1; + +id_err: + my_error(ER_WRONG_ARGUMENTS,MYF(0),"INDEX DIRECORY"); + return 1; +} + + #endif /* WITH_PARTITION_STORAGE_ENGINE */ diff --git a/sql/partition_info.h b/sql/partition_info.h index b7d13e188f3..2859aaec3be 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -290,6 +290,7 @@ private: }; uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); +bool check_partition_dirs(partition_info *part_info); /* Initialize the iterator to return a single partition with given part_id */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 009b81a3893..d79fbed7acb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2364,6 +2364,28 @@ 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; + } + +#ifdef WITH_PARTITION_STORAGE_ENGINE + if (check_partition_dirs(thd->lex->part_info)) + { + res= -1; + break; + } +#endif + /* Fix names if symlinked tables */ if (append_file_to_dir(thd, &create_info.data_file_name, create_table->table_name) || @@ -7354,6 +7376,49 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg, } +/* + 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 +*/ + +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(character_set_filesystem, + (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); +} + + extern int MYSQLparse(void *thd); // from sql_yacc.cc |