From fc9f3efaec61ea3086c1df2942a1157fdf9ca1c2 Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Wed, 1 Dec 2010 13:54:50 +0100 Subject: BUG#58246: INSTALL PLUGIN not secure & crashable When installing plugins, there is a missing check for slash (/) in the path on Windows. Note that on Windows, both / and \ can be used to separate directories. This patch fixes the issue by: - Adding a FN_DIRSEP symbol for all platforms consisting of a string of legal directory separators. - Adding a charset-aware version of strcspn(). - Adding a check_valid_path() function that uses my_strcspn() to check if any FN_DIRSEP character is in the supplied string. - Using the check_valid_path() function in sql_plugin.cc and sql_udf.cc (which means replacing the existing test there). include/config-netware.h: Adding FN_DIRSEP ****** Adding FN_DIRSEP include/config-win.h: Adding FN_DIRSEP ****** Adding FN_DIRSEP include/m_ctype.h: Adding my_strspn() and my_strcspn(). ****** Adding my_strspn() and my_strcspn(). include/my_global.h: Adding FN_DIRSEP ****** Adding FN_DIRSEP mysql-test/t/plugin_not_embedded.test: Adding test that file names containing / is disallowed on *all* platforms. ****** Adding test that file names containing / is disallowed on *all* platforms. sql/sql_plugin.cc: Introducing check_if_path() function for checking if filename is a path to include / on Windows. ****** Introducing check_if_path() function for checking if filename is a path to include / on Windows. sql/sql_udf.cc: Switching to use check_if_path() function. ****** Switching to use check_if_path() function. strings/my_strchr.c: Adding my_strspn() and my_strcspn(). ****** Adding my_strspn() and my_strcspn(). --- sql/sql_plugin.cc | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'sql/sql_plugin.cc') diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index e0fc88c3068..d8423fd153b 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -231,6 +231,26 @@ extern bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists); #endif /* EMBEDDED_LIBRARY */ +/** + Check if the provided path is valid in the sense that it does cause + a relative reference outside the directory. + + @note Currently, this function only check if there are any + characters in FN_DIRSEP in the string, but it might change in the + future. + + @code + check_valid_path("../foo.so") -> true + check_valid_path("foo.so") -> false + @endcode + */ +bool check_valid_path(const char *path, size_t len) +{ + size_t prefix= my_strcspn(files_charset_info, path, path + len, FN_DIRSEP); + return prefix < len; +} + + /**************************************************************************** Value type thunks, allows the C world to play in the C++ world ****************************************************************************/ @@ -354,13 +374,14 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) struct st_plugin_dl *tmp, plugin_dl; void *sym; DBUG_ENTER("plugin_dl_add"); + DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", dl->str, dl->length)); plugin_dir_len= strlen(opt_plugin_dir); /* Ensure that the dll doesn't have a path. This is done to ensure that only approved libraries from the plugin directory are used (to make this even remotely secure). */ - if (my_strchr(files_charset_info, dl->str, dl->str + dl->length, FN_LIBCHAR) || + if (check_valid_path(dl->str, dl->length) || check_string_char_length((LEX_STRING *) dl, "", NAME_CHAR_LEN, system_charset_info, 1) || plugin_dir_len + dl->length + 1 >= FN_REFLEN) -- cgit v1.2.1 From d56a6dd02792e9a6bd5d0a644feb152f4cdae0a1 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Thu, 2 Dec 2010 08:14:43 +0100 Subject: BUG#58246 post-push fix broken DBG build. --- sql/sql_plugin.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql/sql_plugin.cc') diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index d8423fd153b..03a729258ca 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -374,7 +374,8 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) struct st_plugin_dl *tmp, plugin_dl; void *sym; DBUG_ENTER("plugin_dl_add"); - DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", dl->str, dl->length)); + DBUG_PRINT("enter", ("dl->str: '%s', dl->length: %d", + dl->str, (int) dl->length)); plugin_dir_len= strlen(opt_plugin_dir); /* Ensure that the dll doesn't have a path. -- cgit v1.2.1