summaryrefslogtreecommitdiff
path: root/storage/myisam
diff options
context:
space:
mode:
authorNisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com>2017-05-12 09:47:48 +0530
committerNisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com>2017-05-12 09:47:48 +0530
commitb615c3dff885b1ce44fa2275aec8f04c8963ea75 (patch)
treeb739e4235a8417a0812d09ab8f3ca3d628bec8ca /storage/myisam
parent67bec60c726ee25e5c4a82709397c65c4e768e3e (diff)
downloadmariadb-git-b615c3dff885b1ce44fa2275aec8f04c8963ea75.tar.gz
BUG#25451091:CREATE TABLE DATA DIRECTORY / INDEX DIRECTORY
SYMLINK CHECK RACE CONDITIONS ANALYSIS: ========= A potential defect exists in the handling of CREATE TABLE .. DATA DIRECTORY/ INDEX DIRECTORY which gives way to the user to gain access to another user table or a system table. FIX: ==== The lstat and fstat output of the target files are now stored which help in determining the identity of the target files thus preventing the unauthorized access to other files.
Diffstat (limited to 'storage/myisam')
-rw-r--r--storage/myisam/mi_delete_table.c6
-rw-r--r--storage/myisam/mi_open.c50
2 files changed, 42 insertions, 14 deletions
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index b6530334dd2..768b4618928 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@ int mi_delete_table(const char *name)
#endif
fn_format(from,name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
- if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
+ if (my_is_symlink(from, NULL) && (*myisam_test_invalid_symlink)(from))
{
/*
Symlink is pointing to file in data directory.
@@ -44,7 +44,7 @@ int mi_delete_table(const char *name)
DBUG_RETURN(my_errno);
}
fn_format(from,name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
- if (my_is_symlink(from) && (*myisam_test_invalid_symlink)(from))
+ if (my_is_symlink(from, NULL) && (*myisam_test_invalid_symlink)(from))
{
/*
Symlink is pointing to file in data directory.
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 93f70a5d340..1f0cc8e2169 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -78,6 +78,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
ulong rec_per_key_part[HA_MAX_POSSIBLE_KEY*MI_MAX_KEY_SEG];
my_off_t key_root[HA_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
ulonglong max_key_file_length, max_data_file_length;
+ ST_FILE_ID file_id= {0, 0};
DBUG_ENTER("mi_open");
LINT_INIT(m_info);
@@ -89,11 +90,15 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
realpath_err= my_realpath(name_buff,
fn_format(org_name,name,"",MI_NAME_IEXT,4),MYF(0));
- if (my_is_symlink(org_name) &&
- (realpath_err || (*myisam_test_invalid_symlink)(name_buff)))
+ if (my_is_symlink(name_buff, &file_id))
{
- my_errno= HA_WRONG_CREATE_OPTION;
- DBUG_RETURN (NULL);
+ if (realpath_err ||
+ (*myisam_test_invalid_symlink)(name_buff) ||
+ my_is_symlink(name_buff, &file_id))
+ {
+ my_errno= HA_WRONG_CREATE_OPTION;
+ DBUG_RETURN (NULL);
+ }
}
mysql_mutex_lock(&THR_LOCK_myisam);
@@ -113,17 +118,28 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_errno= HA_ERR_CRASHED;
goto err;
});
+ DEBUG_SYNC_C("before_opening_indexfile");
if ((kfile= mysql_file_open(mi_key_file_kfile,
name_buff,
- (open_mode= O_RDWR) | O_SHARE, MYF(0))) < 0)
+ (open_mode= O_RDWR) | O_SHARE | O_NOFOLLOW,
+ MYF(0))) < 0)
{
if ((errno != EROFS && errno != EACCES) ||
mode != O_RDONLY ||
(kfile= mysql_file_open(mi_key_file_kfile,
name_buff,
- (open_mode= O_RDONLY) | O_SHARE, MYF(0))) < 0)
+ (open_mode= O_RDONLY) | O_SHARE | O_NOFOLLOW,
+ MYF(0))) < 0)
goto err;
}
+
+ if (!my_is_same_file(kfile, &file_id))
+ {
+ mysql_file_close(kfile, MYF(0));
+ my_errno= HA_WRONG_CREATE_OPTION;
+ goto err;
+ }
+
share->mode=open_mode;
errpos=1;
if (mysql_file_read(kfile, share->state.header.file_version, head_length,
@@ -1206,14 +1222,16 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name,
{
char *data_name= share->data_file_name;
char real_data_name[FN_REFLEN];
+ ST_FILE_ID file_id= {0, 0};
if (org_name)
{
fn_format(real_data_name,org_name,"",MI_NAME_DEXT,4);
- if (my_is_symlink(real_data_name))
+ if (my_is_symlink(real_data_name, &file_id))
{
if (my_realpath(real_data_name, real_data_name, MYF(0)) ||
- (*myisam_test_invalid_symlink)(real_data_name))
+ (*myisam_test_invalid_symlink)(real_data_name) ||
+ my_is_symlink(real_data_name, &file_id))
{
my_errno= HA_WRONG_CREATE_OPTION;
return 1;
@@ -1221,9 +1239,19 @@ int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share, const char *org_name,
data_name= real_data_name;
}
}
+ DEBUG_SYNC_C("before_opening_datafile");
info->dfile= mysql_file_open(mi_key_file_dfile,
- data_name, share->mode | O_SHARE, MYF(MY_WME));
- return info->dfile >= 0 ? 0 : 1;
+ data_name, share->mode | O_SHARE | O_NOFOLLOW,
+ MYF(MY_WME));
+ if (info->dfile < 0)
+ return 1;
+ if (org_name && !my_is_same_file(info->dfile, &file_id))
+ {
+ mysql_file_close(info->dfile, MYF(0));
+ my_errno= HA_WRONG_CREATE_OPTION;
+ return 1;
+ }
+ return 0;
}