diff options
author | unknown <ingo@mysql.com> | 2005-03-04 11:37:45 +0100 |
---|---|---|
committer | unknown <ingo@mysql.com> | 2005-03-04 11:37:45 +0100 |
commit | 7bd7643ab7b1df5de942422ef0a037718881b3b3 (patch) | |
tree | be5541209e5f5e84db880427fffd18b0e7e9ceb8 /sql/sql_udf.cc | |
parent | aec0408ba9634bc15be77b8507ca8b83ff609e24 (diff) | |
parent | e54b545a966a92677242d6e6f904a10eb73cb707 (diff) | |
download | mariadb-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.cc | 105 |
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; } |