diff options
author | Florian Weimer <fweimer@redhat.com> | 2014-08-26 19:38:59 +0200 |
---|---|---|
committer | Allan McRae <allan@archlinux.org> | 2014-09-05 22:44:12 +1000 |
commit | b8d0acdb33866d0f67ee8a019bdbdaa6a00d0c99 (patch) | |
tree | 74011768bee69cc99444a44aa32ecbab1144d407 | |
parent | 92b410973f872297e0c1bfda06abead4b0a265d1 (diff) | |
download | glibc-b8d0acdb33866d0f67ee8a019bdbdaa6a00d0c99.tar.gz glibc-b8d0acdb33866d0f67ee8a019bdbdaa6a00d0c99.tar.xz glibc-b8d0acdb33866d0f67ee8a019bdbdaa6a00d0c99.zip |
__gconv_translit_find: Disable function [BZ #17187]
This functionality has never worked correctly, and the implementation contained a security vulnerability (CVE-2014-5119). (cherry picked from commit a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8) (cherry picked from commit f9df71e895d3552d557e783fdb9d133328195645) Conflicts: NEWS
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | iconv/gconv_trans.c | 177 |
3 files changed, 19 insertions, 174 deletions
diff --git a/ChangeLog b/ChangeLog index e274c7febb..fdef17a250 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2014-08-26 Florian Weimer <fweimer@redhat.com> + + [BZ #17187] + * iconv/gconv_trans.c (struct known_trans, search_tree, lock, + trans_compare, open_translit, __gconv_translit_find): + Remove module loading code. + 2014-08-01 Stefan Liebler <stli@linux.vnet.ibm.com> * NEWS: Explain the s390 jmp_buf / ucontext_t ABI change diff --git a/NEWS b/NEWS index 352b8a599b..ebcefb5a80 100644 --- a/NEWS +++ b/NEWS @@ -10,7 +10,7 @@ Version 2.19.1 * The following bugs are resolved with this release: 15946, 16545, 16574, 16623, 16695, 16878, 16882, 16885, 16916, 16932, - 16943, 16958, 17048, 17069, 17137. + 16943, 16958, 17048, 17069, 17137, 17263. * Reverted change of ABI data structures for s390 and s390x: On s390 and s390x the size of struct ucontext and jmp_buf was increased in @@ -37,6 +37,13 @@ Version 2.19.1 silently replaced with the "C" locale when running in AT_SECURE mode (e.g., in a SUID program). This is no longer necessary because of the additional checks. + +* Support for loadable gconv transliteration modules has been removed. + The support for transliteration modules has been non-functional for + over a decade, and the removal is prompted by security defects. The + normal gconv conversion modules are still supported. Transliteration + with //TRANSLIT is still possible, and the //IGNORE specifier + continues to be supported. (CVE-2014-5119) Version 2.19 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; } |