diff options
author | Florian Weimer <fweimer@redhat.com> | 2014-08-26 19:38:59 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2014-08-26 19:38:59 +0200 |
commit | a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8 (patch) | |
tree | cc3ae9c647c06ac364e336f9fb06c6c8ac3a6860 /iconv/gconv_trans.c | |
parent | e4e7cfd287686d26fce2218ed5b2d383db5e338a (diff) | |
download | glibc-a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8.tar.gz glibc-a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8.tar.xz glibc-a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8.zip |
__gconv_translit_find: Disable function [BZ #17187]
This functionality has never worked correctly, and the implementation contained a security vulnerability (CVE-2014-5119).
Diffstat (limited to 'iconv/gconv_trans.c')
-rw-r--r-- | iconv/gconv_trans.c | 177 |
1 files changed, 4 insertions, 173 deletions
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c index 1e25854ccf..e0835fc666 100644 --- a/iconv/gconv_trans.c +++ b/iconv/gconv_trans.c @@ -238,181 +238,12 @@ __gconv_transliterate (struct __gconv_step *step, return __GCONV_ILLEGAL_INPUT; } - -/* Structure to represent results of found (or not) transliteration - modules. */ -struct known_trans -{ - /* This structure must remain the first member. */ - struct trans_struct info; - - char *fname; - void *handle; - int open_count; -}; - - -/* Tree with results of previous calls to __gconv_translit_find. */ -static void *search_tree; - -/* We modify global data. */ -__libc_lock_define_initialized (static, lock); - - -/* Compare two transliteration entries. */ -static int -trans_compare (const void *p1, const void *p2) -{ - const struct known_trans *s1 = (const struct known_trans *) p1; - const struct known_trans *s2 = (const struct known_trans *) p2; - - return strcmp (s1->info.name, s2->info.name); -} - - -/* Open (maybe reopen) the module named in the struct. Get the function - and data structure pointers we need. */ -static int -open_translit (struct known_trans *trans) -{ - __gconv_trans_query_fct queryfct; - - trans->handle = __libc_dlopen (trans->fname); - if (trans->handle == NULL) - /* Not available. */ - return 1; - - /* Find the required symbol. */ - queryfct = __libc_dlsym (trans->handle, "gconv_trans_context"); - if (queryfct == NULL) - { - /* We cannot live with that. */ - close_and_out: - __libc_dlclose (trans->handle); - trans->handle = NULL; - return 1; - } - - /* Get the context. */ - if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames) - != 0) - goto close_and_out; - - /* Of course we also have to have the actual function. */ - trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans"); - if (trans->info.trans_fct == NULL) - goto close_and_out; - - /* Now the optional functions. */ - trans->info.trans_init_fct = - __libc_dlsym (trans->handle, "gconv_trans_init"); - trans->info.trans_context_fct = - __libc_dlsym (trans->handle, "gconv_trans_context"); - trans->info.trans_end_fct = - __libc_dlsym (trans->handle, "gconv_trans_end"); - - trans->open_count = 1; - - return 0; -} - - int internal_function __gconv_translit_find (struct trans_struct *trans) { - struct known_trans **found; - const struct path_elem *runp; - int res = 1; - - /* We have to have a name. */ - assert (trans->name != NULL); - - /* Acquire the lock. */ - __libc_lock_lock (lock); - - /* See whether we know this module already. */ - found = __tfind (trans, &search_tree, trans_compare); - if (found != NULL) - { - /* Is this module available? */ - if ((*found)->handle != NULL) - { - /* Maybe we have to reopen the file. */ - if ((*found)->handle != (void *) -1) - /* The object is not unloaded. */ - res = 0; - else if (open_translit (*found) == 0) - { - /* Copy the data. */ - *trans = (*found)->info; - (*found)->open_count++; - res = 0; - } - } - } - else - { - size_t name_len = strlen (trans->name) + 1; - int need_so = 0; - struct known_trans *newp; - - /* We have to continue looking for the module. */ - if (__gconv_path_elem == NULL) - __gconv_get_path (); - - /* See whether we have to append .so. */ - if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0) - need_so = 1; - - /* Create a new entry. */ - newp = (struct known_trans *) malloc (sizeof (struct known_trans) - + (__gconv_max_path_elem_len - + name_len + 3) - + name_len); - if (newp != NULL) - { - char *cp; - - /* Clear the struct. */ - memset (newp, '\0', sizeof (struct known_trans)); - - /* Store a copy of the module name. */ - newp->info.name = cp = (char *) (newp + 1); - cp = __mempcpy (cp, trans->name, name_len); - - newp->fname = cp; - - /* Search in all the directories. */ - for (runp = __gconv_path_elem; runp->name != NULL; ++runp) - { - cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name), - trans->name, name_len); - if (need_so) - memcpy (cp, ".so", sizeof (".so")); - - if (open_translit (newp) == 0) - { - /* We found a module. */ - res = 0; - break; - } - } - - if (res) - newp->fname = NULL; - - /* In any case we'll add the entry to our search tree. */ - if (__tsearch (newp, &search_tree, trans_compare) == NULL) - { - /* Yickes, this should not happen. Unload the object. */ - res = 1; - /* XXX unload here. */ - } - } - } - - __libc_lock_unlock (lock); - - return res; + /* Transliteration module loading has been removed because it never + worked as intended and suffered from a security vulnerability. + Consequently, this function always fails. */ + return 1; } |