Commit 4050910f authored by Sergey Vojtovich's avatar Sergey Vojtovich

BUG#40980 - Drop table can remove another MyISAM table's

            data and index files

It was possible if DATA/INDEX DIRECTORY is pointing to
symlinked MySQL data home directory.

Do not allow to drop data/index files implicitly symlinked
to data home directory. For such tables remove symlink only.
parent 2049d1af
...@@ -168,4 +168,16 @@ Warning 1618 <DATA DIRECTORY> option ignored ...@@ -168,4 +168,16 @@ Warning 1618 <DATA DIRECTORY> option ignored
Warning 1618 <INDEX DIRECTORY> option ignored Warning 1618 <INDEX DIRECTORY> option ignored
DROP TABLE t1; DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE; SET @@SQL_MODE=@OLD_SQL_MODE;
#
# BUG#40980 - Drop table can remove another MyISAM table's
# data and index files
#
CREATE TABLE user(a INT) DATA DIRECTORY='MYSQL_TMP_DIR/mysql'
INDEX DIRECTORY='MYSQL_TMP_DIR/mysql';
FLUSH TABLE user;
# Symlinking mysql database to tmpdir
FLUSH TABLE mysql.user;
DROP TABLE user;
FLUSH TABLE mysql.user;
SELECT * FROM mysql.user;
End of 5.1 tests End of 5.1 tests
...@@ -249,4 +249,26 @@ eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTO ...@@ -249,4 +249,26 @@ eval CREATE TABLE t1(a INT) DATA DIRECTORY='$MYSQLTEST_VARDIR/tmp' INDEX DIRECTO
DROP TABLE t1; DROP TABLE t1;
SET @@SQL_MODE=@OLD_SQL_MODE; SET @@SQL_MODE=@OLD_SQL_MODE;
--echo #
--echo # BUG#40980 - Drop table can remove another MyISAM table's
--echo # data and index files
--echo #
--mkdir $MYSQL_TMP_DIR/mysql
--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR
eval CREATE TABLE user(a INT) DATA DIRECTORY='$MYSQL_TMP_DIR/mysql'
INDEX DIRECTORY='$MYSQL_TMP_DIR/mysql';
FLUSH TABLE user;
--echo # Symlinking mysql database to tmpdir
--remove_file $MYSQL_TMP_DIR/mysql/user.MYD
--remove_file $MYSQL_TMP_DIR/mysql/user.MYI
--rmdir $MYSQL_TMP_DIR/mysql
--exec ln -s $MYSQLD_DATADIR/mysql $MYSQL_TMP_DIR/mysql
FLUSH TABLE mysql.user;
DROP TABLE user;
FLUSH TABLE mysql.user;
--disable_result_log
SELECT * FROM mysql.user;
--enable_result_log
--remove_file $MYSQL_TMP_DIR/mysql
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -19,6 +19,41 @@ ...@@ -19,6 +19,41 @@
#include "fulltext.h" #include "fulltext.h"
/**
Remove MyISAM data/index file safely
@details
If name is a symlink and file it is pointing to is not in
data directory, file is also removed.
@param name file to remove
@returns
0 on success or my_errno on failure
*/
static int _mi_safe_delete_file(const char *name)
{
DBUG_ENTER("_mi_safe_delete_file");
if (my_is_symlink(name) && (*myisam_test_invalid_symlink)(name))
{
/*
Symlink is pointing to file in data directory.
Remove symlink, keep file.
*/
if (my_delete(name, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
else
{
if (my_delete_with_symlink(name, MYF(MY_WME)))
DBUG_RETURN(my_errno);
}
DBUG_RETURN(0);
}
int mi_delete_table(const char *name) int mi_delete_table(const char *name)
{ {
char from[FN_REFLEN]; char from[FN_REFLEN];
...@@ -58,12 +93,12 @@ int mi_delete_table(const char *name) ...@@ -58,12 +93,12 @@ int mi_delete_table(const char *name)
#endif /* USE_RAID */ #endif /* USE_RAID */
fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
if (my_delete_with_symlink(from, MYF(MY_WME))) if (_mi_safe_delete_file(from))
DBUG_RETURN(my_errno); DBUG_RETURN(my_errno);
fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
#ifdef USE_RAID #ifdef USE_RAID
if (raid_type) if (raid_type)
DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0); DBUG_RETURN(my_raid_delete(from, raid_chunks, MYF(MY_WME)) ? my_errno : 0);
#endif #endif
DBUG_RETURN(my_delete_with_symlink(from, MYF(MY_WME)) ? my_errno : 0); DBUG_RETURN(_mi_safe_delete_file(from));
} }
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