summaryrefslogtreecommitdiff
path: root/sql/sql_udf.cc
diff options
context:
space:
mode:
authorunknown <ingo@mysql.com>2005-03-04 11:37:45 +0100
committerunknown <ingo@mysql.com>2005-03-04 11:37:45 +0100
commit7bd7643ab7b1df5de942422ef0a037718881b3b3 (patch)
treebe5541209e5f5e84db880427fffd18b0e7e9ceb8 /sql/sql_udf.cc
parentaec0408ba9634bc15be77b8507ca8b83ff609e24 (diff)
parente54b545a966a92677242d6e6f904a10eb73cb707 (diff)
downloadmariadb-git-7bd7643ab7b1df5de942422ef0a037718881b3b3.tar.gz
Merge with after merge fix
BitKeeper/deleted/.del-create.c~96cecc433c0c2242: Auto merged include/my_global.h: Auto merged myisam/mi_create.c: Auto merged sql/ha_myisam.cc: Auto merged sql/mysql_priv.h: Auto merged BitKeeper/deleted/.del-errmsg.txt~f96b7055cac394e: Auto merged BitKeeper/deleted/.del-mrg_create.c~b747c8ec2b801f6: Auto merged sql/table.cc: Auto merged sql/sql_udf.cc: After merge fix
Diffstat (limited to 'sql/sql_udf.cc')
-rw-r--r--sql/sql_udf.cc105
1 files changed, 69 insertions, 36 deletions
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index ec47fb055e2..c7c0bf2034f 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -74,32 +74,49 @@ static HASH udf_hash;
static rw_lock_t THR_LOCK_udf;
-static udf_func *add_udf(LEX_STRING *name, Item_result ret, char *dl,
- Item_udftype typ);
+static udf_func *add_udf(LEX_STRING *name, Item_result ret,
+ char *dl, Item_udftype typ);
static void del_udf(udf_func *udf);
static void *find_udf_dl(const char *dl);
-
-static void init_syms(udf_func *tmp)
+static char *init_syms(udf_func *tmp, char *nm)
{
- char nm[MAX_FIELD_NAME+16],*end;
+ char *end;
+
+ if (!((tmp->func= dlsym(tmp->dlhandle, tmp->name.str))))
+ return tmp->name.str;
- tmp->func = dlsym(tmp->dlhandle, tmp->name.str);
end=strmov(nm,tmp->name.str);
- (void) strmov(end,"_init");
- tmp->func_init = dlsym(tmp->dlhandle, nm);
- (void) strmov(end,"_deinit");
- tmp->func_deinit = dlsym(tmp->dlhandle, nm);
+
if (tmp->type == UDFTYPE_AGGREGATE)
{
- (void)strmov( end, "_clear" );
- tmp->func_clear = dlsym( tmp->dlhandle, nm );
- (void)strmov( end, "_add" );
- tmp->func_add = dlsym( tmp->dlhandle, nm );
- /* Give error if _clear and _add doesn't exists */
- if (!tmp->func_clear || ! tmp->func_add)
- tmp->func= 0;
+ (void)strmov(end, "_clear");
+ if (!((tmp->func_clear= dlsym(tmp->dlhandle, nm))))
+ return nm;
+ (void)strmov(end, "_add");
+ if (!((tmp->func_add= dlsym(tmp->dlhandle, nm))))
+ return nm;
+ }
+
+ (void) strmov(end,"_deinit");
+ tmp->func_deinit= dlsym(tmp->dlhandle, nm);
+
+ (void) strmov(end,"_init");
+ tmp->func_init= dlsym(tmp->dlhandle, nm);
+
+ /*
+ to prefent loading "udf" from, e.g. libc.so
+ let's ensure that at least one auxiliary symbol is defined
+ */
+ if (!tmp->func_init && !tmp->func_deinit && tmp->type != UDFTYPE_AGGREGATE)
+ {
+ if (opt_allow_suspicious_udfs)
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), nm);
+ else
+ return nm;
}
+
+ return 0;
}
extern "C" byte* get_hash_key(const byte *buff,uint *length,
@@ -111,7 +128,7 @@ extern "C" byte* get_hash_key(const byte *buff,uint *length,
}
/*
-** Read all predeclared functions from func@mysql and accept all that
+** Read all predeclared functions from mysql.func and accept all that
** can be used.
*/
@@ -153,7 +170,7 @@ void udf_init()
if (simple_open_n_lock_tables(new_thd, &tables))
{
DBUG_PRINT("error",("Can't open udf table"));
- sql_print_error("Can't open the mysql/func table. Please run the mysql_install_db script to create it.");
+ sql_print_error("Can't open the mysql.func table. Please run the mysql_install_db script to create it.");
goto end;
}
@@ -171,10 +188,23 @@ void udf_init()
if (table->s->fields >= 4) // New func table
udftype=(Item_udftype) table->field[3]->val_int();
- if (!(tmp = add_udf(&name,(Item_result) table->field[1]->val_int(),
- dl_name, udftype)))
+ /*
+ 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).
+ */
+ if (strchr(dl_name, '/') || name.length > NAME_LEN)
+ {
+ sql_print_error("Invalid row in mysql.func table for function '%.64s'",
+ name.str);
+ continue;
+ }
+
+
+ if (!(tmp= add_udf(&name,(Item_result) table->field[1]->val_int(),
+ dl_name, udftype)))
{
- sql_print_error("Can't alloc memory for udf function: name");
+ sql_print_error("Can't alloc memory for udf function: '%.64s'", name.str);
continue;
}
@@ -191,13 +221,15 @@ void udf_init()
new_dl=1;
}
tmp->dlhandle = dl;
- init_syms(tmp);
- if (!tmp->func)
{
- sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), name);
- del_udf(tmp);
- if (new_dl)
- dlclose(dl);
+ char buf[MAX_FIELD_NAME+16], *missing;
+ if ((missing= init_syms(tmp, buf)))
+ {
+ sql_print_error(ER(ER_CANT_FIND_DL_ENTRY), missing);
+ del_udf(tmp);
+ if (new_dl)
+ dlclose(dl);
+ }
}
}
if (error > 0)
@@ -239,7 +271,7 @@ void udf_free()
{
initialized= 0;
rwlock_destroy(&THR_LOCK_udf);
- }
+ }
DBUG_VOID_RETURN;
}
@@ -407,12 +439,13 @@ int mysql_create_function(THD *thd,udf_func *udf)
new_dl=1;
}
udf->dlhandle=dl;
- init_syms(udf);
-
- if (udf->func == NULL)
{
- my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), udf->name);
- goto err;
+ char buf[MAX_FIELD_NAME+16], *missing;
+ if ((missing= init_syms(udf, buf)))
+ {
+ my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), missing);
+ goto err;
+ }
}
udf->name.str=strdup_root(&mem,udf->name.str);
udf->dl=strdup_root(&mem,udf->dl);
@@ -425,7 +458,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
u_d->func_clear=udf->func_clear;
u_d->func_add=udf->func_add;
- /* create entry in mysql/func table */
+ /* create entry in mysql.func table */
bzero((char*) &tables,sizeof(tables));
tables.db= (char*) "mysql";
@@ -445,7 +478,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
close_thread_tables(thd);
if (error)
{
- my_error(ER_ERROR_ON_WRITE, MYF(0), "func@mysql", error);
+ my_error(ER_ERROR_ON_WRITE, MYF(0), "mysql.func", error);
del_udf(u_d);
goto err;
}