1 |
From a1a6a401ab0a3c9f15fb7eaebbdcee24192254e8 Mon Sep 17 00:00:00 2001 |
2 |
From: Florian Weimer <fweimer@redhat.com> |
3 |
Date: Tue, 26 Aug 2014 19:38:59 +0200 |
4 |
Subject: [PATCH] __gconv_translit_find: Disable function [BZ #17187] |
5 |
|
6 |
This functionality has never worked correctly, and the implementation |
7 |
contained a security vulnerability (CVE-2014-5119). |
8 |
--- |
9 |
ChangeLog | 7 ++ |
10 |
NEWS | 9 ++- |
11 |
iconv/gconv_trans.c | 177 +------------------------------------------------- |
12 |
3 files changed, 19 insertions(+), 174 deletions(-) |
13 |
|
14 |
#diff --git a/ChangeLog b/ChangeLog |
15 |
#index 119e979..254a595 100644 |
16 |
#--- a/ChangeLog |
17 |
#+++ b/ChangeLog |
18 |
#@@ -1,3 +1,10 @@ |
19 |
#+2014-08-26 Florian Weimer <fweimer@redhat.com> |
20 |
#+ |
21 |
#+ [BZ #17187] |
22 |
#+ * iconv/gconv_trans.c (struct known_trans, search_tree, lock, |
23 |
#+ trans_compare, open_translit, __gconv_translit_find): |
24 |
#+ Remove module loading code. |
25 |
#+ |
26 |
# 2014-08-26 Allan McRae <allan@archlinux.org> |
27 |
# |
28 |
# * po/vi.po: Update Vietnamese translation from translation project. |
29 |
#diff --git a/NEWS b/NEWS |
30 |
#index 28da6e5..d5c78be 100644 |
31 |
#--- a/NEWS |
32 |
#+++ b/NEWS |
33 |
#@@ -23,7 +23,7 @@ Version 2.20 |
34 |
# 16966, 16967, 16977, 16978, 16984, 16990, 16996, 17009, 17022, 17031, |
35 |
# 17042, 17048, 17050, 17058, 17061, 17062, 17069, 17075, 17078, 17079, |
36 |
# 17084, 17086, 17088, 17092, 17097, 17125, 17135, 17137, 17150, 17153, |
37 |
#- 17213, 17259, 17261, 17262, 17263. |
38 |
#+ 17187, 17213, 17259, 17261, 17262, 17263. |
39 |
# |
40 |
# * Reverted change of ABI data structures for s390 and s390x: |
41 |
# On s390 and s390x the size of struct ucontext and jmp_buf was increased in |
42 |
#@@ -108,6 +108,13 @@ Version 2.20 |
43 |
# handle the new instruction encodings. This is known to affect Valgrind |
44 |
# versions up through 3.9 (but will be fixed in the forthcoming 3.10 |
45 |
# release), and might affect other tools that do instruction emulation. |
46 |
#+ |
47 |
#+* Support for loadable gconv transliteration modules has been removed. |
48 |
#+ The support for transliteration modules has been non-functional for |
49 |
#+ over a decade, and the removal is prompted by security defects. The |
50 |
#+ normal gconv conversion modules are still supported. Transliteration |
51 |
#+ with //TRANSLIT is still possible, and the //IGNORE specifier |
52 |
#+ continues to be supported. (CVE-2014-5519) |
53 |
# |
54 |
# Version 2.19 |
55 |
# |
56 |
diff --git a/iconv/gconv_trans.c b/iconv/gconv_trans.c |
57 |
index 1e25854..e0835fc 100644 |
58 |
--- a/iconv/gconv_trans.c |
59 |
+++ b/iconv/gconv_trans.c |
60 |
@@ -238,181 +238,12 @@ __gconv_transliterate (struct __gconv_step *step, |
61 |
return __GCONV_ILLEGAL_INPUT; |
62 |
} |
63 |
|
64 |
- |
65 |
-/* Structure to represent results of found (or not) transliteration |
66 |
- modules. */ |
67 |
-struct known_trans |
68 |
-{ |
69 |
- /* This structure must remain the first member. */ |
70 |
- struct trans_struct info; |
71 |
- |
72 |
- char *fname; |
73 |
- void *handle; |
74 |
- int open_count; |
75 |
-}; |
76 |
- |
77 |
- |
78 |
-/* Tree with results of previous calls to __gconv_translit_find. */ |
79 |
-static void *search_tree; |
80 |
- |
81 |
-/* We modify global data. */ |
82 |
-__libc_lock_define_initialized (static, lock); |
83 |
- |
84 |
- |
85 |
-/* Compare two transliteration entries. */ |
86 |
-static int |
87 |
-trans_compare (const void *p1, const void *p2) |
88 |
-{ |
89 |
- const struct known_trans *s1 = (const struct known_trans *) p1; |
90 |
- const struct known_trans *s2 = (const struct known_trans *) p2; |
91 |
- |
92 |
- return strcmp (s1->info.name, s2->info.name); |
93 |
-} |
94 |
- |
95 |
- |
96 |
-/* Open (maybe reopen) the module named in the struct. Get the function |
97 |
- and data structure pointers we need. */ |
98 |
-static int |
99 |
-open_translit (struct known_trans *trans) |
100 |
-{ |
101 |
- __gconv_trans_query_fct queryfct; |
102 |
- |
103 |
- trans->handle = __libc_dlopen (trans->fname); |
104 |
- if (trans->handle == NULL) |
105 |
- /* Not available. */ |
106 |
- return 1; |
107 |
- |
108 |
- /* Find the required symbol. */ |
109 |
- queryfct = __libc_dlsym (trans->handle, "gconv_trans_context"); |
110 |
- if (queryfct == NULL) |
111 |
- { |
112 |
- /* We cannot live with that. */ |
113 |
- close_and_out: |
114 |
- __libc_dlclose (trans->handle); |
115 |
- trans->handle = NULL; |
116 |
- return 1; |
117 |
- } |
118 |
- |
119 |
- /* Get the context. */ |
120 |
- if (queryfct (trans->info.name, &trans->info.csnames, &trans->info.ncsnames) |
121 |
- != 0) |
122 |
- goto close_and_out; |
123 |
- |
124 |
- /* Of course we also have to have the actual function. */ |
125 |
- trans->info.trans_fct = __libc_dlsym (trans->handle, "gconv_trans"); |
126 |
- if (trans->info.trans_fct == NULL) |
127 |
- goto close_and_out; |
128 |
- |
129 |
- /* Now the optional functions. */ |
130 |
- trans->info.trans_init_fct = |
131 |
- __libc_dlsym (trans->handle, "gconv_trans_init"); |
132 |
- trans->info.trans_context_fct = |
133 |
- __libc_dlsym (trans->handle, "gconv_trans_context"); |
134 |
- trans->info.trans_end_fct = |
135 |
- __libc_dlsym (trans->handle, "gconv_trans_end"); |
136 |
- |
137 |
- trans->open_count = 1; |
138 |
- |
139 |
- return 0; |
140 |
-} |
141 |
- |
142 |
- |
143 |
int |
144 |
internal_function |
145 |
__gconv_translit_find (struct trans_struct *trans) |
146 |
{ |
147 |
- struct known_trans **found; |
148 |
- const struct path_elem *runp; |
149 |
- int res = 1; |
150 |
- |
151 |
- /* We have to have a name. */ |
152 |
- assert (trans->name != NULL); |
153 |
- |
154 |
- /* Acquire the lock. */ |
155 |
- __libc_lock_lock (lock); |
156 |
- |
157 |
- /* See whether we know this module already. */ |
158 |
- found = __tfind (trans, &search_tree, trans_compare); |
159 |
- if (found != NULL) |
160 |
- { |
161 |
- /* Is this module available? */ |
162 |
- if ((*found)->handle != NULL) |
163 |
- { |
164 |
- /* Maybe we have to reopen the file. */ |
165 |
- if ((*found)->handle != (void *) -1) |
166 |
- /* The object is not unloaded. */ |
167 |
- res = 0; |
168 |
- else if (open_translit (*found) == 0) |
169 |
- { |
170 |
- /* Copy the data. */ |
171 |
- *trans = (*found)->info; |
172 |
- (*found)->open_count++; |
173 |
- res = 0; |
174 |
- } |
175 |
- } |
176 |
- } |
177 |
- else |
178 |
- { |
179 |
- size_t name_len = strlen (trans->name) + 1; |
180 |
- int need_so = 0; |
181 |
- struct known_trans *newp; |
182 |
- |
183 |
- /* We have to continue looking for the module. */ |
184 |
- if (__gconv_path_elem == NULL) |
185 |
- __gconv_get_path (); |
186 |
- |
187 |
- /* See whether we have to append .so. */ |
188 |
- if (name_len <= 4 || memcmp (&trans->name[name_len - 4], ".so", 3) != 0) |
189 |
- need_so = 1; |
190 |
- |
191 |
- /* Create a new entry. */ |
192 |
- newp = (struct known_trans *) malloc (sizeof (struct known_trans) |
193 |
- + (__gconv_max_path_elem_len |
194 |
- + name_len + 3) |
195 |
- + name_len); |
196 |
- if (newp != NULL) |
197 |
- { |
198 |
- char *cp; |
199 |
- |
200 |
- /* Clear the struct. */ |
201 |
- memset (newp, '\0', sizeof (struct known_trans)); |
202 |
- |
203 |
- /* Store a copy of the module name. */ |
204 |
- newp->info.name = cp = (char *) (newp + 1); |
205 |
- cp = __mempcpy (cp, trans->name, name_len); |
206 |
- |
207 |
- newp->fname = cp; |
208 |
- |
209 |
- /* Search in all the directories. */ |
210 |
- for (runp = __gconv_path_elem; runp->name != NULL; ++runp) |
211 |
- { |
212 |
- cp = __mempcpy (__stpcpy ((char *) newp->fname, runp->name), |
213 |
- trans->name, name_len); |
214 |
- if (need_so) |
215 |
- memcpy (cp, ".so", sizeof (".so")); |
216 |
- |
217 |
- if (open_translit (newp) == 0) |
218 |
- { |
219 |
- /* We found a module. */ |
220 |
- res = 0; |
221 |
- break; |
222 |
- } |
223 |
- } |
224 |
- |
225 |
- if (res) |
226 |
- newp->fname = NULL; |
227 |
- |
228 |
- /* In any case we'll add the entry to our search tree. */ |
229 |
- if (__tsearch (newp, &search_tree, trans_compare) == NULL) |
230 |
- { |
231 |
- /* Yickes, this should not happen. Unload the object. */ |
232 |
- res = 1; |
233 |
- /* XXX unload here. */ |
234 |
- } |
235 |
- } |
236 |
- } |
237 |
- |
238 |
- __libc_lock_unlock (lock); |
239 |
- |
240 |
- return res; |
241 |
+ /* Transliteration module loading has been removed because it never |
242 |
+ worked as intended and suffered from a security vulnerability. |
243 |
+ Consequently, this function always fails. */ |
244 |
+ return 1; |
245 |
} |
246 |
-- |
247 |
1.7.1 |
248 |
|