Bug#11835 CREATE FUNCTION crashes server

 - Update for 5.1
 - Add "have_dlopen"
 - Remove requirement to load udf's only in "opt_plugin_dir" 
parent 1d953c31
...@@ -1443,13 +1443,4 @@ do { doubleget_union _tmp; \ ...@@ -1443,13 +1443,4 @@ do { doubleget_union _tmp; \
#define dlerror() "" #define dlerror() ""
#endif #endif
/* FreeBSD 2.2.2 does not define RTLD_NOW) */
#ifndef RTLD_NOW
#define RTLD_NOW 1
#endif
#ifndef HAVE_DLERROR
#define dlerror() ""
#endif
#endif /* my_global_h */ #endif /* my_global_h */
# #
# To check if the udf_example.so is available, # Check if server has support for loading udf's
# try to load one function from it. # i.e it will support dlopen
#
# #
--require r/have_udf.require --require r/have_udf.require
--disable_abort_on_error disable_query_log;
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so'; show variables like "have_dlopen";
--disable_query_log enable_query_log;
DROP FUNCTION metaphon;
--enable_query_log
--enable_abort_on_error
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so'; Variable_name Value
have_dlopen YES
...@@ -2,7 +2,7 @@ drop table if exists t1; ...@@ -2,7 +2,7 @@ drop table if exists t1;
CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so'; CREATE FUNCTION metaphon RETURNS STRING SONAME 'udf_example.so';
CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so'; CREATE FUNCTION myfunc_double RETURNS REAL SONAME 'udf_example.so';
CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME 'udf_example.so'; CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME 'udf_example.so';
ERROR HY000: Can't find function 'myfunc_nonexist' in library ERROR HY000: Can't find symbol 'myfunc_nonexist' in library
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so'; CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME 'udf_example.so';
CREATE FUNCTION sequence RETURNS INTEGER SONAME "udf_example.so"; CREATE FUNCTION sequence RETURNS INTEGER SONAME "udf_example.so";
CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so'; CREATE FUNCTION lookup RETURNS STRING SONAME 'udf_example.so';
......
...@@ -2807,9 +2807,6 @@ longlong Item_func_udf_int::val_int() ...@@ -2807,9 +2807,6 @@ longlong Item_func_udf_int::val_int()
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
DBUG_ENTER("Item_func_udf_int::val_int"); DBUG_ENTER("Item_func_udf_int::val_int");
DBUG_PRINT("info",("result_type: %d arg_count: %d",
args[0]->result_type(), arg_count));
DBUG_RETURN(udf.val_int(&null_value)); DBUG_RETURN(udf.val_int(&null_value));
} }
......
...@@ -1444,7 +1444,7 @@ extern handlerton myisammrg_hton; ...@@ -1444,7 +1444,7 @@ extern handlerton myisammrg_hton;
extern handlerton heap_hton; extern handlerton heap_hton;
extern SHOW_COMP_OPTION have_row_based_replication; extern SHOW_COMP_OPTION have_row_based_replication;
extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink; extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_dlopen;
extern SHOW_COMP_OPTION have_query_cache; extern SHOW_COMP_OPTION have_query_cache;
extern SHOW_COMP_OPTION have_geometry, have_rtree_keys; extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
extern SHOW_COMP_OPTION have_crypt; extern SHOW_COMP_OPTION have_crypt;
......
...@@ -564,7 +564,7 @@ CHARSET_INFO *national_charset_info, *table_alias_charset; ...@@ -564,7 +564,7 @@ CHARSET_INFO *national_charset_info, *table_alias_charset;
CHARSET_INFO *character_set_filesystem; CHARSET_INFO *character_set_filesystem;
SHOW_COMP_OPTION have_row_based_replication; SHOW_COMP_OPTION have_row_based_replication;
SHOW_COMP_OPTION have_openssl, have_symlink, have_query_cache; SHOW_COMP_OPTION have_openssl, have_symlink, have_dlopen, have_query_cache;
SHOW_COMP_OPTION have_geometry, have_rtree_keys; SHOW_COMP_OPTION have_geometry, have_rtree_keys;
SHOW_COMP_OPTION have_crypt, have_compress; SHOW_COMP_OPTION have_crypt, have_compress;
...@@ -1163,13 +1163,13 @@ void clean_up(bool print_message) ...@@ -1163,13 +1163,13 @@ void clean_up(bool print_message)
set_var_free(); set_var_free();
free_charsets(); free_charsets();
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */ (void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
#ifdef HAVE_DLOPEN
if (!opt_noacl) if (!opt_noacl)
{ {
#ifdef HAVE_DLOPEN
udf_free(); udf_free();
}
#endif #endif
plugin_free(); plugin_free();
}
if (tc_log) if (tc_log)
tc_log->close(); tc_log->close();
xid_cache_free(); xid_cache_free();
...@@ -7078,6 +7078,11 @@ static void mysql_init_variables(void) ...@@ -7078,6 +7078,11 @@ static void mysql_init_variables(void)
#else #else
have_symlink=SHOW_OPTION_YES; have_symlink=SHOW_OPTION_YES;
#endif #endif
#ifdef HAVE_DLOPEN
have_dlopen=SHOW_OPTION_YES;
#else
have_dlopen=SHOW_OPTION_NO;
#endif
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
have_query_cache=SHOW_OPTION_YES; have_query_cache=SHOW_OPTION_YES;
#else #else
......
...@@ -630,6 +630,7 @@ sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine", ...@@ -630,6 +630,7 @@ sys_var_have_variable sys_have_blackhole_db("have_blackhole_engine",
sys_var_have_variable sys_have_compress("have_compress", &have_compress); sys_var_have_variable sys_have_compress("have_compress", &have_compress);
sys_var_have_variable sys_have_crypt("have_crypt", &have_crypt); sys_var_have_variable sys_have_crypt("have_crypt", &have_crypt);
sys_var_have_variable sys_have_csv_db("have_csv", &have_csv_db); sys_var_have_variable sys_have_csv_db("have_csv", &have_csv_db);
sys_var_have_variable sys_have_dlopen("have_dlopen", &have_dlopen);
sys_var_have_variable sys_have_example_db("have_example_engine", sys_var_have_variable sys_have_example_db("have_example_engine",
&have_example_db); &have_example_db);
sys_var_have_variable sys_have_federated_db("have_federated_engine", sys_var_have_variable sys_have_federated_db("have_federated_engine",
...@@ -754,6 +755,7 @@ SHOW_VAR init_vars[]= { ...@@ -754,6 +755,7 @@ SHOW_VAR init_vars[]= {
{sys_have_compress.name, (char*) &have_compress, SHOW_HAVE}, {sys_have_compress.name, (char*) &have_compress, SHOW_HAVE},
{sys_have_crypt.name, (char*) &have_crypt, SHOW_HAVE}, {sys_have_crypt.name, (char*) &have_crypt, SHOW_HAVE},
{sys_have_csv_db.name, (char*) &have_csv_db, SHOW_HAVE}, {sys_have_csv_db.name, (char*) &have_csv_db, SHOW_HAVE},
{sys_have_dlopen.name, (char*) &have_dlopen, SHOW_HAVE},
{sys_have_example_db.name, (char*) &have_example_db, SHOW_HAVE}, {sys_have_example_db.name, (char*) &have_example_db, SHOW_HAVE},
{sys_have_federated_db.name,(char*) &have_federated_db, SHOW_HAVE}, {sys_have_federated_db.name,(char*) &have_federated_db, SHOW_HAVE},
{sys_have_geometry.name, (char*) &have_geometry, SHOW_HAVE}, {sys_have_geometry.name, (char*) &have_geometry, SHOW_HAVE},
......
...@@ -94,8 +94,10 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl) ...@@ -94,8 +94,10 @@ static st_plugin_dl *plugin_dl_insert_or_reuse(struct st_plugin_dl *plugin_dl)
static inline void free_plugin_mem(struct st_plugin_dl *p) static inline void free_plugin_mem(struct st_plugin_dl *p)
{ {
#ifdef HAVE_DLOPEN
if (p->handle) if (p->handle)
dlclose(p->handle); dlclose(p->handle);
#endif
my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR)); my_free(p->dl.str, MYF(MY_ALLOW_ZERO_PTR));
if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION) if (p->version != MYSQL_PLUGIN_INTERFACE_VERSION)
my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr)p->plugins, MYF(MY_ALLOW_ZERO_PTR));
......
...@@ -114,7 +114,7 @@ void udf_init() ...@@ -114,7 +114,7 @@ void udf_init()
READ_RECORD read_record_info; READ_RECORD read_record_info;
TABLE *table; TABLE *table;
int error; int error;
DBUG_ENTER("ufd_init"); DBUG_ENTER("udf_init");
if (initialized) if (initialized)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -177,7 +177,6 @@ void udf_init() ...@@ -177,7 +177,6 @@ void udf_init()
continue; continue;
} }
if (!(tmp= add_udf(&name,(Item_result) table->field[1]->val_int(), if (!(tmp= add_udf(&name,(Item_result) table->field[1]->val_int(),
dl_name, udftype))) dl_name, udftype)))
{ {
...@@ -188,13 +187,10 @@ void udf_init() ...@@ -188,13 +187,10 @@ void udf_init()
void *dl = find_udf_dl(tmp->dl); void *dl = find_udf_dl(tmp->dl);
if (dl == NULL) if (dl == NULL)
{ {
char dlpath[FN_REFLEN]; if (!(dl= dlopen(tmp->dl, RTLD_NOW)))
strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl,
NullS);
if (!(dl= dlopen(dlpath, RTLD_NOW)))
{ {
/* Print warning to log */ /* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), dlpath, 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 */ /* Keep the udf in the hash so that we can remove it later */
continue; continue;
} }
...@@ -415,14 +411,12 @@ int mysql_create_function(THD *thd,udf_func *udf) ...@@ -415,14 +411,12 @@ int mysql_create_function(THD *thd,udf_func *udf)
} }
if (!(dl = find_udf_dl(udf->dl))) if (!(dl = find_udf_dl(udf->dl)))
{ {
char dlpath[FN_REFLEN]; if (!(dl = dlopen(udf->dl, RTLD_NOW)))
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)", DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
dlpath, errno, dlerror())); udf->dl, errno, dlerror()));
my_error(ER_CANT_OPEN_LIBRARY, MYF(0), my_error(ER_CANT_OPEN_LIBRARY, MYF(0),
dlpath, errno, dlerror()); udf->dl, errno, dlerror());
goto err; goto err;
} }
new_dl=1; new_dl=1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment