You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.4 KiB
208 lines
5.4 KiB
commit a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8 |
|
Author: Florian Weimer <fweimer@redhat.com> |
|
Date: Tue Aug 26 19:38:59 2014 +0200 |
|
|
|
__gconv_translit_find: Disable function [BZ #17187] |
|
|
|
This functionality has never worked correctly, and the implementation |
|
contained a security vulnerability (CVE-2014-5119). |
|
|
|
2014-08-21 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. |
|
|
|
diff --git glibc-2.17-c758a686/iconv/gconv_trans.c glibc-2.17-c758a686/iconv/gconv_trans.c |
|
index 1e25854..d71c029 100644 |
|
--- glibc-2.17-c758a686/iconv/gconv_trans.c |
|
+++ glibc-2.17-c758a686/iconv/gconv_trans.c |
|
@@ -238,181 +238,11 @@ __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; |
|
+ /* This function always fails. Transliteration module loading is |
|
+ not implemented. */ |
|
+ return 1; |
|
} |
|
-- |
|
1.9.3 |
|
|
|
|