Commit 1af41943 authored by unknown's avatar unknown

Bug#32167 another privilege bypass with DATA/INDEX DIRECORY(3rd version for 5.1)

added new function test_if_data_home_dir() which checks that
path does not contain mysql data home directory.
Using of 'mysql data home'/'any db name' in
DATA DIRECTORY & INDEX DIRECTORY is disallowed


mysql-test/r/partition.result:
  test result
mysql-test/r/partition_not_windows.result:
  result fix
mysql-test/r/partition_symlink.result:
  result fix
mysql-test/r/symlink.result:
  test result update
mysql-test/t/partition.test:
  test case
mysql-test/t/partition_not_windows.test:
  test case update
mysql-test/t/partition_symlink.test:
  test case update
mysql-test/t/symlink.test:
  test case
sql/mysql_priv.h:
  new variable mysql_unpacked_real_data_home
sql/mysqld.cc:
  new variable mysql_unpacked_real_data_home
sql/partition_info.cc:
  new check_partition_dirs() which checks
  data directory and index directory for partition elements
sql/partition_info.h:
  new check_partition_dirs() which checks
  data directory and index directory for partition elements
sql/sql_parse.cc:
  added new function test_if_data_home_dir() which checks that
  path does not contain mysql data home directory.
  Using of 'mysql data home'/'any db name' in
  DATA DIRECTORY & INDEX DIRECTORY is disallowed
parent 9c0ee58f
......@@ -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),
......
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;
......
......@@ -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):
......
......@@ -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)
......@@ -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;
......@@ -1574,6 +1574,44 @@ ALTER TABLE t1 OPTIMIZE PARTITION p1 EXTENDED;
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
#
......
......@@ -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.
......
......@@ -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
......@@ -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';
......@@ -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[],
......
......@@ -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);
......
......@@ -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 */
......@@ -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 */
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment