mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
b27fd90ad3
TOCTOU bug. The path is checked to be valid, symlinks are resolved. Then the resolved path is opened. Between the check and the open, there's a window when one can replace some path component with a symlink, bypassing validity checks. Fix: after we resolved all symlinks in the path, don't allow open() to resolve symlinks, there should be none. Compared to the old MyISAM/Aria code: * fastpath. Opening of not-symlinked files is just one open(), no fn_format() and lstat() anymore. * opening of symlinked tables doesn't do fn_format() and lstat() either. it also doesn't to realpath() (which was lstat-ing every path component), instead if opens every path component with O_PATH. * share->data_file_name stores realpath(path) not readlink(path). So, SHOW CREATE TABLE needs to do lstat/readlink() now (see ::info()), and certain error messages (cannot open file "XXX") show the real file path with all symlinks resolved.
39 lines
1.2 KiB
Text
39 lines
1.2 KiB
Text
set default_storage_engine=Aria;
|
|
call mtr.add_suppression("File.*t1.* not found");
|
|
create table mysql.t1 (a int, b char(16), index(a));
|
|
insert mysql.t1 values (100, 'test'),(101,'test');
|
|
create table t1 (a int, b char(16), index(a))
|
|
data directory="MYSQLTEST_VARDIR/tmp/foo";
|
|
insert t1 values (200, 'some'),(201,'some');
|
|
select * from t1;
|
|
a b
|
|
200 some
|
|
201 some
|
|
flush tables;
|
|
set debug_sync='mi_open_datafile SIGNAL ok WAIT_FOR go';
|
|
select * from t1;
|
|
set debug_sync='now WAIT_FOR ok';
|
|
set debug_sync='now SIGNAL go';
|
|
ERROR HY000: File 'MYSQLTEST_VARDIR/tmp/foo/t1.MAD' not found (Errcode: 20)
|
|
flush tables;
|
|
drop table if exists t1;
|
|
create table t1 (a int, b char(16), index (a))
|
|
index directory="MYSQLTEST_VARDIR/tmp/foo";
|
|
insert t1 values (200, 'some'),(201,'some');
|
|
explain select a from t1;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 SIMPLE t1 index NULL a 5 NULL 2 Using index
|
|
select a from t1;
|
|
a
|
|
200
|
|
201
|
|
flush tables;
|
|
set debug_sync='mi_open_kfile SIGNAL waiting WAIT_FOR run';
|
|
select a from t1;
|
|
set debug_sync='now WAIT_FOR waiting';
|
|
set debug_sync='now SIGNAL run';
|
|
ERROR HY000: Can't find file: 't1' (errno: 20)
|
|
flush tables;
|
|
drop table if exists t1;
|
|
drop table mysql.t1;
|
|
set debug_sync='RESET';
|