diff options
-rw-r--r-- | mysql-test/r/temp_table_symlink.result | 13 | ||||
-rw-r--r-- | mysql-test/t/temp_table_symlink.test | 32 | ||||
-rw-r--r-- | storage/maria/ma_create.c | 6 | ||||
-rw-r--r-- | storage/myisam/mi_create.c | 6 |
4 files changed, 51 insertions, 6 deletions
diff --git a/mysql-test/r/temp_table_symlink.result b/mysql-test/r/temp_table_symlink.result new file mode 100644 index 00000000000..1c5c68170ff --- /dev/null +++ b/mysql-test/r/temp_table_symlink.result @@ -0,0 +1,13 @@ +create table d1 (a int); +create temporary table t1 (a int); +create temporary table t2 (a int); +Got one of the listed errors +create temporary table t3 (a int) engine=Aria; +Got one of the listed errors +select * from information_schema.columns where table_schema='test'; +Got one of the listed errors +flush tables; +select * from d1; +a +drop temporary table t1; +drop table d1; diff --git a/mysql-test/t/temp_table_symlink.test b/mysql-test/t/temp_table_symlink.test new file mode 100644 index 00000000000..9297b472805 --- /dev/null +++ b/mysql-test/t/temp_table_symlink.test @@ -0,0 +1,32 @@ +source include/not_windows.inc; + +# +# MDEV-23569 temporary tables can overwrite existing files +# + +let datadir=`select @@datadir`; +create table d1 (a int); +create temporary table t1 (a int); +perl; +chdir "$ENV{MYSQL_TMP_DIR}/mysqld.1/"; +for (<#sql*.MYI>) { + /^#sql(.*)_([0-9a-f]+_)([0-9a-f]+)\.MYI$/ or die; + symlink "$ENV{datadir}/test/d1.MYI", sprintf "#sql$1_$2%x.MYI", hex($3)+1; + symlink "$ENV{datadir}/test/d1.MYI", sprintf "#sql$1_$2%x.MAI", hex($3)+1; + symlink "$ENV{datadir}/test/d1.MYI", sprintf "#sql$1_$2%x.MAI", hex($3)+2; + symlink "$ENV{datadir}/test/d1.MYI", "#sql_$1_0.MAI"; +} +EOF + +error 1,1030; +create temporary table t2 (a int); +error 1,1030; +create temporary table t3 (a int) engine=Aria; +error 1,1030; +select * from information_schema.columns where table_schema='test'; + +flush tables; +select * from d1; +drop temporary table t1; +remove_files_wildcard $MYSQL_TMP_DIR/mysqld.1 *sql*; +drop table d1; diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c index 263d8a307b1..e1d2d89020d 100644 --- a/storage/maria/ma_create.c +++ b/storage/maria/ma_create.c @@ -322,7 +322,7 @@ int maria_create(const char *name, enum data_file_type datafile_type, { options|= HA_OPTION_TMP_TABLE; tmp_table= TRUE; - create_mode|= O_NOFOLLOW; + create_mode|= O_NOFOLLOW | (internal_table ? 0 : O_EXCL); /* "CREATE TEMPORARY" tables are not crash-safe (dropped at restart) */ ci->transactional= FALSE; flags&= ~HA_CREATE_PAGE_CHECKSUM; @@ -887,8 +887,8 @@ int maria_create(const char *name, enum data_file_type datafile_type, { char *iext= strrchr(name, '.'); int have_iext= iext && !strcmp(iext, MARIA_NAME_IEXT); - fn_format(kfilename, name, "", MARIA_NAME_IEXT, - MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | + fn_format(kfilename, name, "", MARIA_NAME_IEXT, MY_UNPACK_FILENAME | + (internal_table ? 0 : MY_RETURN_REAL_PATH) | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); klinkname_ptr= NullS; /* diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c index 855ac8337b9..7d6095b8a09 100644 --- a/storage/myisam/mi_create.c +++ b/storage/myisam/mi_create.c @@ -184,7 +184,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, if (flags & HA_CREATE_TMP_TABLE) { options|= HA_OPTION_TMP_TABLE; - create_mode|= O_NOFOLLOW; + create_mode|= O_NOFOLLOW | (internal_table ? 0 : O_EXCL); } if (flags & HA_CREATE_CHECKSUM || (options & HA_OPTION_CHECKSUM)) { @@ -618,8 +618,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, { char *iext= strrchr(name, '.'); int have_iext= iext && !strcmp(iext, MI_NAME_IEXT); - fn_format(kfilename, name, "", MI_NAME_IEXT, - MY_UNPACK_FILENAME | MY_RETURN_REAL_PATH | + fn_format(kfilename, name, "", MI_NAME_IEXT, MY_UNPACK_FILENAME | + (internal_table ? 0 : MY_RETURN_REAL_PATH) | (have_iext ? MY_REPLACE_EXT : MY_APPEND_EXT)); klinkname_ptr= 0; /* Replace the current file */ |