summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@mysql.com>2008-07-28 19:22:12 +0500
committerAlexey Botchkov <holyfoot@mysql.com>2008-07-28 19:22:12 +0500
commit15f925607e956dc96c1d401330989bc270125788 (patch)
treecca238dfb698bc850fe41ec7b65e253bb331a4dc
parentd9b2730a454d5a00c8a64a0311c6ec8768601429 (diff)
downloadmariadb-git-15f925607e956dc96c1d401330989bc270125788.tar.gz
Bug#37428 Potential security issue with UDFs - linux shellcode execution.
plugin_dir option backported from 5.1 per-file messages: sql/mysql_priv.h Bug#37428 Potential security issue with UDFs - linux shellcode execution. opt_plugin_dir and opt_plugin_dir_ptr declared. sql/mysqld.cc Bug#37428 Potential security issue with UDFs - linux shellcode execution. 'plugin_dir' option added sql/set_var.cc Bug#37428 Potential security issue with UDFs - linux shellcode execution. 'plugin_dir' option added. sql/sql_udf.cc Bug#37428 Potential security issue with UDFs - linux shellcode execution. opt_plugin_dir added to the udf->dl path. Warn if it's not specified. sql/unireg.h Bug#37428 Potential security issue with UDFs - linux shellcode execution. PLUGINDIR defined.
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/mysqld.cc11
-rw-r--r--sql/set_var.cc1
-rw-r--r--sql/sql_udf.cc26
-rw-r--r--sql/unireg.h3
5 files changed, 41 insertions, 3 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f3bda4e5819..c1694cbbbe4 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1362,6 +1362,9 @@ extern char *default_tz_name;
extern my_bool opt_large_pages;
extern uint opt_large_page_size;
+extern char *opt_plugin_dir_ptr;
+extern char opt_plugin_dir[FN_REFLEN];
+
extern MYSQL_LOG mysql_log,mysql_slow_log,mysql_bin_log;
extern FILE *bootstrap_file;
extern int bootstrap_error;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 7edc3b91752..d591ce46af7 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -324,6 +324,9 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
/* static variables */
+char opt_plugin_dir[FN_REFLEN];
+char *opt_plugin_dir_ptr;
+
static bool lower_case_table_names_used= 0;
static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
@@ -4984,6 +4987,7 @@ enum options_mysqld
OPT_OLD_STYLE_USER_LIMITS,
OPT_LOG_SLOW_ADMIN_STATEMENTS,
OPT_TABLE_LOCK_WAIT_TIMEOUT,
+ OPT_PLUGIN_DIR,
OPT_PORT_OPEN_TIMEOUT,
OPT_MERGE,
OPT_PROFILING,
@@ -6223,6 +6227,10 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.optimizer_search_depth,
(gptr*) &max_system_variables.optimizer_search_depth,
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
+ {"plugin_dir", OPT_PLUGIN_DIR,
+ "Directory for plugins.",
+ (gptr*) &opt_plugin_dir_ptr, (gptr*) &opt_plugin_dir_ptr, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
"The size of the buffer that is allocated when preloading indexes",
(gptr*) &global_system_variables.preload_buff_size,
@@ -7761,6 +7769,9 @@ static void fix_paths(void)
(void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
(void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
(void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
+ (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
+ "", "");
+ opt_plugin_dir_ptr= opt_plugin_dir;
char *sharedir=get_relative_path(SHAREDIR);
if (test_if_hard_path(sharedir))
diff --git a/sql/set_var.cc b/sql/set_var.cc
index eb381bfecf4..a0ddef0b386 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1036,6 +1036,7 @@ struct show_var_st init_vars[]= {
{sys_optimizer_search_depth.name,(char*) &sys_optimizer_search_depth,
SHOW_SYS},
{"pid_file", (char*) pidfile_name, SHOW_CHAR},
+ {"plugin_dir", (char*) opt_plugin_dir, SHOW_CHAR},
{"port", (char*) &mysqld_port, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
#ifdef ENABLED_PROFILING
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 34ca18d5c39..e3a0230d2fb 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -214,7 +214,17 @@ void udf_init()
void *dl = find_udf_dl(tmp->dl);
if (dl == NULL)
{
- if (!(dl = dlopen(tmp->dl, RTLD_NOW)))
+ char dlpath[FN_REFLEN];
+ if (*opt_plugin_dir)
+ strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl,
+ NullS);
+ else
+ {
+ strxnmov(dlpath, sizeof(dlpath)-1, tmp->dl, NullS);
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "plugin_dir was not specified");
+ }
+ if (!(dl = dlopen(dlpath, RTLD_NOW)))
{
/* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl,errno,dlerror());
@@ -443,8 +453,18 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
if (!(dl = find_udf_dl(udf->dl)))
{
- DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", udf->dl));
- if (!(dl = dlopen(udf->dl, RTLD_NOW)))
+ char dlpath[FN_REFLEN];
+ if (*opt_plugin_dir)
+ strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl,
+ NullS);
+ else
+ {
+ strxnmov(dlpath, sizeof(dlpath)-1, udf->dl, NullS);
+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "plugin_dir was not specified");
+ }
+ DBUG_PRINT("info", ("Calling dlopen, udf->dl: %s", dlpath));
+ if (!(dl = dlopen(dlpath, RTLD_NOW)))
{
DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
udf->dl,errno,dlerror()));
diff --git a/sql/unireg.h b/sql/unireg.h
index 1326b22c8c9..8e01e6222e6 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -35,6 +35,9 @@
#ifndef SHAREDIR
#define SHAREDIR "share/"
#endif
+#ifndef PLUGINDIR
+#define PLUGINDIR "lib/plugin"
+#endif
#define ER(X) errmesg[(X) - ER_ERROR_FIRST]
#define ER_SAFE(X) (((X) >= ER_ERROR_FIRST && (X) <= ER_ERROR_LAST) ? ER(X) : "Invalid error code")