summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_plugin.cc23
-rw-r--r--sql/sql_plugin.h1
-rw-r--r--sql/sql_udf.cc12
3 files changed, 25 insertions, 11 deletions
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)
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index 004d0d5abb7..72984865807 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -131,6 +131,7 @@ extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name);
extern bool plugin_register_builtin(struct st_mysql_plugin *plugin);
extern void plugin_thdvar_init(THD *thd);
extern void plugin_thdvar_cleanup(THD *thd);
+extern bool check_valid_path(const char *path, size_t length);
typedef my_bool (plugin_foreach_func)(THD *thd,
plugin_ref plugin,
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index d455a66c4f2..1d5335f0652 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -173,10 +173,7 @@ void udf_init()
On windows we must check both FN_LIBCHAR and '/'.
*/
- if (my_strchr(files_charset_info, dl_name,
- dl_name + strlen(dl_name), FN_LIBCHAR) ||
- IF_WIN(my_strchr(files_charset_info, dl_name,
- dl_name + strlen(dl_name), '/'), 0) ||
+ if (check_valid_path(dl_name, strlen(dl_name)) ||
check_string_char_length(&name, "", NAME_CHAR_LEN,
system_charset_info, 1))
{
@@ -416,13 +413,8 @@ int mysql_create_function(THD *thd,udf_func *udf)
Ensure that the .dll doesn't have a path
This is done to ensure that only approved dll from the system
directories are used (to make this even remotely secure).
-
- On windows we must check both FN_LIBCHAR and '/'.
*/
- if (my_strchr(files_charset_info, udf->dl,
- udf->dl + strlen(udf->dl), FN_LIBCHAR) ||
- IF_WIN(my_strchr(files_charset_info, udf->dl,
- udf->dl + strlen(udf->dl), '/'), 0))
+ if (check_valid_path(udf->dl, strlen(udf->dl)))
{
my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0));
DBUG_RETURN(1);