summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <joerg/mysqldev@mysql.com/production.mysql.com>2007-11-15 10:55:47 +0100
committerunknown <joerg/mysqldev@mysql.com/production.mysql.com>2007-11-15 10:55:47 +0100
commit0679860358d42f2e6bb4c018c982549b9a09586f (patch)
tree34976825a249a1a49fc6be84a3bbf0e7a24e7f14
parentf48c09e96faf73b032500b11385f25a780e22fa9 (diff)
downloadmariadb-git-0679860358d42f2e6bb4c018c982549b9a09586f.tar.gz
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. (This is a copy of changeset 2007/11/06 18:09:33+04:00 svoj@mysql.com and its merge changesets on the way from 4.0 up to 5.0) mysql-test/r/symlink.result: A test case for BUG#32111, with after merge fix, and using proper variable. mysql-test/t/symlink.test: A test case for BUG#32111, with after merge fix, and using proper variable. mysys/my_symlink2.c: Return an error when the file to which the symlink points exist.
-rw-r--r--mysql-test/r/symlink.result6
-rw-r--r--mysql-test/t/symlink.test12
-rw-r--r--mysys/my_symlink2.c11
3 files changed, 28 insertions, 1 deletions
diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result
index 18299bf4298..833adbeb851 100644
--- a/mysql-test/r/symlink.result
+++ b/mysql-test/r/symlink.result
@@ -99,6 +99,12 @@ t1 CREATE TABLE `t1` (
`b` int(11) default NULL
) 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` (
diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test
index 8c67a4c1048..7eaeaa00c0a 100644
--- a/mysql-test/t/symlink.test
+++ b/mysql-test/t/symlink.test
@@ -125,6 +125,18 @@ show create table t1;
drop table t1;
#
+# BUG#32111 - Security Breach via DATA/INDEX DIRECORY and RENAME TABLE
+#
+--replace_result $MYSQLTEST_VARDIR TEST_DIR
+eval CREATE TABLE t1(a INT)
+DATA DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql'
+INDEX DIRECTORY='$MYSQLTEST_VARDIR/master-data/mysql';
+--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)
#
diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c
index e2493874097..ee0a45cf93b 100644
--- a/mysys/my_symlink2.c
+++ b/mysys/my_symlink2.c
@@ -126,6 +126,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)
@@ -134,6 +135,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))
@@ -145,7 +154,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 */