From ff4b438be005a3cffb5100db93e10da0f7980922 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 Nov 2007 18:09:33 +0400 Subject: [PATCH 1/2] BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE RENAME TABLE against a table with DATA/INDEX DIRECTORY overwrites the file to which the symlink points. This is security issue, because it is possible to create a table with some name in some non-system database and set DATA/INDEX DIRECTORY to mysql system database. Renaming this table to one of mysql system tables (e.g. user, host) would overwrite the system table. Return an error when the file to which the symlink points exist. mysql-test/r/symlink.result: A test case for BUG#32111. mysql-test/t/symlink.test: A test case for BUG#32111. mysys/my_symlink2.c: Return an error when the file to which the symlink points exist. --- mysql-test/r/symlink.result | 6 ++++++ mysql-test/t/symlink.test | 12 ++++++++++++ mysys/my_symlink2.c | 11 ++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index d07a8613883..e2b26cb508c 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -84,3 +84,9 @@ t1 CREATE TABLE `t1` ( `b` int(11) default NULL ) TYPE=MyISAM drop table t1; +CREATE TABLE t1(a INT) +DATA DIRECTORY='TEST_DIR/var/master-data/mysql' +INDEX DIRECTORY='TEST_DIR/var/master-data/mysql'; +RENAME TABLE t1 TO user; +Can't create/write to file 'TEST_DIR/var/master-data/mysql/user.MYI' (Errcode: 17) +DROP TABLE t1; diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 7a42a60054e..9750e6fdfdd 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -112,3 +112,15 @@ eval alter table t1 index directory="$MYSQL_TEST_DIR/var/log"; enable_query_log; show create table t1; drop table t1; + +# +# BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE +# +--replace_result $MYSQL_TEST_DIR TEST_DIR +eval CREATE TABLE t1(a INT) +DATA DIRECTORY='$MYSQL_TEST_DIR/var/master-data/mysql' +INDEX DIRECTORY='$MYSQL_TEST_DIR/var/master-data/mysql'; +--replace_result $MYSQL_TEST_DIR TEST_DIR +--error 1 +RENAME TABLE t1 TO user; +DROP TABLE t1; diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c index 913f632fbb4..4d58699412a 100644 --- a/mysys/my_symlink2.c +++ b/mysys/my_symlink2.c @@ -120,6 +120,7 @@ int my_rename_with_symlink(const char *from, const char *to, myf MyFlags) int was_symlink= (!my_disable_symlinks && !my_readlink(link_name, from, MYF(0))); int result=0; + int name_is_different; DBUG_ENTER("my_rename_with_symlink"); if (!was_symlink) @@ -128,6 +129,14 @@ int my_rename_with_symlink(const char *from, const char *to, myf MyFlags) /* Change filename that symlink pointed to */ strmov(tmp_name, to); fn_same(tmp_name,link_name,1); /* Copy dir */ + name_is_different= strcmp(link_name, tmp_name); + if (name_is_different && !access(tmp_name, F_OK)) + { + my_errno= EEXIST; + if (MyFlags & MY_WME) + my_error(EE_CANTCREATEFILE, MYF(0), tmp_name, EEXIST); + DBUG_RETURN(1); + } /* Create new symlink */ if (my_symlink(tmp_name, to, MyFlags)) @@ -139,7 +148,7 @@ int my_rename_with_symlink(const char *from, const char *to, myf MyFlags) the same basename and different directories. */ - if (strcmp(link_name, tmp_name) && my_rename(link_name, tmp_name, MyFlags)) + if (name_is_different && my_rename(link_name, tmp_name, MyFlags)) { int save_errno=my_errno; my_delete(to, MyFlags); /* Remove created symlink */ From 88701b45a935016c31af3bd6817dd4ee4c7ccd37 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Nov 2007 15:15:16 +0400 Subject: [PATCH 2/2] After merge fix. --- mysql-test/r/symlink.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index cc54233107a..81798b2dc20 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -94,7 +94,7 @@ CREATE TABLE t1(a INT) DATA DIRECTORY='TEST_DIR/var/master-data/mysql' INDEX DIRECTORY='TEST_DIR/var/master-data/mysql'; RENAME TABLE t1 TO user; -Can't create/write to file 'TEST_DIR/var/master-data/mysql/user.MYI' (Errcode: 17) +ERROR HY000: Can't create/write to file 'TEST_DIR/var/master-data/mysql/user.MYI' (Errcode: 17) DROP TABLE t1; show create table t1; Table Create Table