Blob Blame History Raw
Back-port upstream fix for CVE-2007-5969.

diff -Naur mysql-5.0.45.orig/mysql-test/r/symlink.result mysql-5.0.45/mysql-test/r/symlink.result
--- mysql-5.0.45.orig/mysql-test/r/symlink.result	2007-07-04 09:49:09.000000000 -0400
+++ mysql-5.0.45/mysql-test/r/symlink.result	2007-12-13 12:28:59.000000000 -0500
@@ -99,6 +99,12 @@
   `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 -Naur mysql-5.0.45.orig/mysql-test/t/symlink.test mysql-5.0.45/mysql-test/t/symlink.test
--- mysql-5.0.45.orig/mysql-test/t/symlink.test	2007-07-04 09:49:09.000000000 -0400
+++ mysql-5.0.45/mysql-test/t/symlink.test	2007-12-13 12:28:59.000000000 -0500
@@ -125,6 +125,18 @@
 drop table t1;
 
 #
+# BUG#32111 <http://bugs.mysql.com/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 -Naur mysql-5.0.45.orig/mysys/my_symlink2.c mysql-5.0.45/mysys/my_symlink2.c
--- mysql-5.0.45.orig/mysys/my_symlink2.c	2007-07-04 09:06:25.000000000 -0400
+++ mysql-5.0.45/mysys/my_symlink2.c	2007-12-13 12:28:59.000000000 -0500
@@ -124,6 +124,7 @@
   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)
@@ -132,6 +133,14 @@
   /* 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))
@@ -143,7 +152,7 @@
     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 */