Commit dd7c52d1 authored by Sergey Petrunya's avatar Sergey Petrunya

Merge from mysql-5.6 fix for bug#11761752 (was already partially merged)

parent 99851177
...@@ -150,6 +150,66 @@ int check_if_legal_tablename(const char *name) ...@@ -150,6 +150,66 @@ int check_if_legal_tablename(const char *name)
} }
#ifdef __WIN__
/**
Checks if the drive letter supplied is valid or not. Valid drive
letters are A to Z, both lower case and upper case.
@param drive_letter : The drive letter to validate.
@return TRUE if the drive exists, FALSE otherwise.
*/
static my_bool does_drive_exists(char drive_letter)
{
DWORD drive_mask= GetLogicalDrives();
drive_letter= toupper(drive_letter);
return (drive_letter >= 'A' && drive_letter <= 'Z') &&
(drive_mask & (0x1 << (drive_letter - 'A')));
}
/**
Verifies if the file name supplied is allowed or not. On Windows
file names with a colon (:) are not allowed because such file names
store data in Alternate Data Streams which can be used to hide
the data.
@param name contains the file name with or without path
@param length contains the length of file name
@param allow_current_dir TRUE if paths like C:foobar are allowed,
FALSE otherwise
@return TRUE if the file name is allowed, FALSE otherwise.
*/
my_bool is_filename_allowed(const char *name __attribute__((unused)),
size_t length __attribute__((unused)),
my_bool allow_current_dir __attribute__((unused)))
{
/*
For Windows, check if the file name contains : character.
Start from end of path and search if the file name contains :
*/
const char* ch = NULL;
for (ch= name + length - 1; ch >= name; --ch)
{
if (FN_LIBCHAR == *ch || '/' == *ch)
break;
else if (':' == *ch)
{
/*
File names like C:foobar.txt are allowed since the syntax means
file foobar.txt in current directory of C drive. However file
names likes CC:foobar are not allowed since this syntax means ADS
foobar in file CC.
*/
return (allow_current_dir && (ch - name == 1) &&
does_drive_exists(*name));
}
}
return TRUE;
} /* is_filename_allowed */
#endif /* __WIN__ */
#if defined(__WIN__) || defined(__EMX__) #if defined(__WIN__) || defined(__EMX__)
...@@ -171,6 +231,9 @@ int check_if_legal_filename(const char *path) ...@@ -171,6 +231,9 @@ int check_if_legal_filename(const char *path)
const char **reserved_name; const char **reserved_name;
DBUG_ENTER("check_if_legal_filename"); DBUG_ENTER("check_if_legal_filename");
if (!is_filename_allowed(path, strlen(path), TRUE))
DBUG_RETURN(1);
path+= dirname_length(path); /* To start of filename */ path+= dirname_length(path); /* To start of filename */
if (!(end= strchr(path, FN_EXTCHAR))) if (!(end= strchr(path, FN_EXTCHAR)))
end= strend(path); end= strend(path);
......
...@@ -3170,6 +3170,14 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var) ...@@ -3170,6 +3170,14 @@ static bool check_log_path(sys_var *self, THD *thd, set_var *var)
if (!path_length) if (!path_length)
return true; return true;
if (!is_filename_allowed(var->save_result.string_value.str,
var->save_result.string_value.length, TRUE))
{
my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
self->name.str, var->save_result.string_value.str);
return true;
}
MY_STAT f_stat; MY_STAT f_stat;
if (my_stat(path, &f_stat, MYF(0))) if (my_stat(path, &f_stat, MYF(0)))
......
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