diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2013-07-05 19:40:34 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2013-07-05 19:40:34 +0400 |
commit | dd7c52d19e541dcd88aef30fffa4e9f0e33c847f (patch) | |
tree | c89c55d290c6a9c4dccf131ab9e7ceee205b9950 /mysys/my_access.c | |
parent | 99851177700fa15cc8c79e4f3641fd32fee03a6a (diff) | |
download | mariadb-git-dd7c52d19e541dcd88aef30fffa4e9f0e33c847f.tar.gz |
Merge from mysql-5.6 fix for bug#11761752 (was already partially merged)
Diffstat (limited to 'mysys/my_access.c')
-rw-r--r-- | mysys/my_access.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/mysys/my_access.c b/mysys/my_access.c index 453d3e29cdf..c5b1361da81 100644 --- a/mysys/my_access.c +++ b/mysys/my_access.c @@ -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__) @@ -171,6 +231,9 @@ int check_if_legal_filename(const char *path) const char **reserved_name; 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 */ if (!(end= strchr(path, FN_EXTCHAR))) end= strend(path); |