diff options
author | unknown <svoj@mysql.com/june.mysql.com> | 2007-05-18 16:23:46 +0500 |
---|---|---|
committer | unknown <svoj@mysql.com/june.mysql.com> | 2007-05-18 16:23:46 +0500 |
commit | 7839da601c2577d5f7c7844fa4230c043321a44a (patch) | |
tree | d313b7e649f394611b5da508133b316e05974670 /sql/sql_udf.cc | |
parent | 0ea67375efc66950d691ce7bdb5cab8eb0a158d5 (diff) | |
download | mariadb-git-7839da601c2577d5f7c7844fa4230c043321a44a.tar.gz |
BUG#28341 - Security issue still in library loading
UDF can be created from any library in any part of the server
LD_LIBRARY_PATH.
Allow to load udfs only from plugin_dir.
On windows, refuse to open udf in case it's path contains a slash.
No good test case for this bug because of imperfect error message
that includes error code and error string when it fails to dlopen a
library.
mysql-test/mysql-test-run.pl:
Since plugins are allowed to be open only from plugin_dir:
- there is no sence to update LD_LIBRARY_PATH
- there is no sence to add plugin_dir arg by default
- set UDF_EXAMPLE_LIB_OPT and EXAMPLE_PLUGIN_OPT to be used by
udf and plugin tests accordingly.
mysql-test/r/plugin.result:
Updated test result (we report addition warning).
sql/sql_udf.cc:
Allow to load udfs only from plugin_dir.
On windows, refuse to open udf in case it's path contains a slash.
mysql-test/t/plugin-master.opt:
New BitKeeper file ``mysql-test/t/plugin-master.opt''
mysql-test/t/udf-master.opt:
New BitKeeper file ``mysql-test/t/udf-master.opt''
Diffstat (limited to 'sql/sql_udf.cc')
-rw-r--r-- | sql/sql_udf.cc | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 89084c21c0c..505f7a9a765 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -169,11 +169,15 @@ void udf_init() 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, dl_name, - dl_name + strlen(dl_name), FN_LIBCHAR) || - check_string_char_length(&name, "", NAME_CHAR_LEN, - system_charset_info, 1)) + dl_name + strlen(dl_name), FN_LIBCHAR) || + IF_WIN(my_strchr(files_charset_info, dl_name, + dl_name + strlen(dl_name), '/'), 0) || + check_string_char_length(&name, "", NAME_CHAR_LEN, + system_charset_info, 1)) { sql_print_error("Invalid row in mysql.func table for function '%.64s'", name.str); @@ -190,10 +194,13 @@ void udf_init() void *dl = find_udf_dl(tmp->dl); if (dl == NULL) { - if (!(dl= dlopen(tmp->dl, RTLD_NOW))) + char dlpath[FN_REFLEN]; + strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl, + NullS); + if (!(dl= dlopen(dlpath, RTLD_NOW))) { /* Print warning to log */ - sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl, errno, dlerror()); + sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl, errno, dlerror()); /* Keep the udf in the hash so that we can remove it later */ continue; } @@ -394,8 +401,13 @@ 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 (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)) { my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0)); DBUG_RETURN(1); @@ -422,10 +434,12 @@ int mysql_create_function(THD *thd,udf_func *udf) } if (!(dl = find_udf_dl(udf->dl))) { - if (!(dl = dlopen(udf->dl, RTLD_NOW))) + char dlpath[FN_REFLEN]; + strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl, NullS); + if (!(dl = dlopen(dlpath, RTLD_NOW))) { DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)", - udf->dl, errno, dlerror())); + udf->dl, errno, dlerror())); my_error(ER_CANT_OPEN_LIBRARY, MYF(0), udf->dl, errno, dlerror()); goto err; |