glibc: fix CVE-2014-5119 by Debian patch

Changed files
+207
pkgs
development
libraries
+1
pkgs/development/libraries/glibc/2.19/common.nix
···
./fix-math.patch
./cve-2014-0475.patch
+
./cve-2014-5119.patch
];
postPatch = ''
+206
pkgs/development/libraries/glibc/2.19/cve-2014-5119.patch
···
+
http://anonscm.debian.org/viewvc/pkg-glibc/glibc-package/trunk/debian/patches/any/cvs-CVE-2014-5119.diff?revision=6248&view=co
+
+
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-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.
+
+
--- 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;
+
}