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 | |
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''
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 23 | ||||
-rw-r--r-- | mysql-test/r/plugin.result | 3 | ||||
-rw-r--r-- | mysql-test/t/plugin-master.opt | 1 | ||||
-rw-r--r-- | mysql-test/t/udf-master.opt | 1 | ||||
-rw-r--r-- | sql/sql_udf.cc | 30 |
5 files changed, 30 insertions, 28 deletions
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a305b1d052d..b8d750c6d15 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1767,22 +1767,6 @@ sub environment_setup () { } # -------------------------------------------------------------------------- - # Add the path where mysqld will find udf_example.so - # -------------------------------------------------------------------------- - if ( $lib_udf_example ) - { - push(@ld_library_paths, dirname($lib_udf_example)); - } - - # -------------------------------------------------------------------------- - # Add the path where mysqld will find ha_example.so - # -------------------------------------------------------------------------- - if ( $lib_example_plugin ) - { - push(@ld_library_paths, dirname($lib_example_plugin)); - } - - # -------------------------------------------------------------------------- # Valgrind need to be run with debug libraries otherwise it's almost # impossible to add correct supressions, that means if "/usr/lib/debug" # is available, it should be added to @@ -2060,12 +2044,16 @@ sub environment_setup () { # ---------------------------------------------------- $ENV{'UDF_EXAMPLE_LIB'}= ($lib_udf_example ? basename($lib_udf_example) : ""); + $ENV{'UDF_EXAMPLE_LIB_OPT'}= + ($lib_udf_example ? "--plugin_dir=" . dirname($lib_udf_example) : ""); # ---------------------------------------------------- # Add the path where mysqld will find ha_example.so # ---------------------------------------------------- $ENV{'EXAMPLE_PLUGIN'}= ($lib_example_plugin ? basename($lib_example_plugin) : ""); + $ENV{'EXAMPLE_PLUGIN_OPT'}= + ($lib_example_plugin ? "--plugin_dir=" . dirname($lib_example_plugin) : ""); # ---------------------------------------------------- # We are nice and report a bit about our settings @@ -3821,9 +3809,6 @@ sub mysqld_arguments ($$$$) { mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); } } - - mtr_add_arg($args, "%s--plugin_dir=%s", $prefix, - dirname($lib_example_plugin)); } else { diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 44641858fca..6005bdcae8d 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -1,6 +1,7 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE; Warnings: -Error 1286 Unknown table engine 'EXAMPLE' +Warning 1286 Unknown table engine 'EXAMPLE' +Warning 1266 Using storage engine MyISAM for table 't1' DROP TABLE t1; INSTALL PLUGIN example SONAME 'ha_example.so'; INSTALL PLUGIN EXAMPLE SONAME 'ha_example.so'; diff --git a/mysql-test/t/plugin-master.opt b/mysql-test/t/plugin-master.opt new file mode 100644 index 00000000000..367d5233e0e --- /dev/null +++ b/mysql-test/t/plugin-master.opt @@ -0,0 +1 @@ +$EXAMPLE_PLUGIN_OPT diff --git a/mysql-test/t/udf-master.opt b/mysql-test/t/udf-master.opt new file mode 100644 index 00000000000..7d8786c156a --- /dev/null +++ b/mysql-test/t/udf-master.opt @@ -0,0 +1 @@ +$UDF_EXAMPLE_LIB_OPT 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; |