diff options
author | Anuj Mittal <anuj.mittal@intel.com> | 2019-04-29 14:26:33 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2019-04-30 12:05:23 +0100 |
commit | e2cc220b0aa9725d673b16293b73d6b470fdf4d4 (patch) | |
tree | 6be9ec37a67bc5baf78bc1f634609eb6dd1883d9 /meta | |
parent | e7c2bc67b51aff57fe3d6c1caf22f457565deede (diff) | |
download | poky-e2cc220b0aa9725d673b16293b73d6b470fdf4d4.tar.gz |
gcc: fix CVE-2018-18484
(From OE-Core rev: ac6af654f50aa6f3057dee0de806f5dfae10e4a8)
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-8.3.inc | 1 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-8.3/0041-Add-a-recursion-limit-to-libiberty-s-demangling-code.patch | 325 |
2 files changed, 326 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-8.3.inc b/meta/recipes-devtools/gcc/gcc-8.3.inc index 88a9df2049..fe9c7c3602 100644 --- a/meta/recipes-devtools/gcc/gcc-8.3.inc +++ b/meta/recipes-devtools/gcc/gcc-8.3.inc | |||
@@ -71,6 +71,7 @@ SRC_URI = "\ | |||
71 | file://0038-Re-introduce-spe-commandline-options.patch \ | 71 | file://0038-Re-introduce-spe-commandline-options.patch \ |
72 | file://0039-riscv-Disable-multilib-for-OE.patch \ | 72 | file://0039-riscv-Disable-multilib-for-OE.patch \ |
73 | file://0040-powerpc-powerpc64-Add-support-for-musl-ldso.patch \ | 73 | file://0040-powerpc-powerpc64-Add-support-for-musl-ldso.patch \ |
74 | file://0041-Add-a-recursion-limit-to-libiberty-s-demangling-code.patch \ | ||
74 | " | 75 | " |
75 | SRC_URI[md5sum] = "65b210b4bfe7e060051f799e0f994896" | 76 | SRC_URI[md5sum] = "65b210b4bfe7e060051f799e0f994896" |
76 | SRC_URI[sha256sum] = "64baadfe6cc0f4947a84cb12d7f0dfaf45bb58b7e92461639596c21e02d97d2c" | 77 | SRC_URI[sha256sum] = "64baadfe6cc0f4947a84cb12d7f0dfaf45bb58b7e92461639596c21e02d97d2c" |
diff --git a/meta/recipes-devtools/gcc/gcc-8.3/0041-Add-a-recursion-limit-to-libiberty-s-demangling-code.patch b/meta/recipes-devtools/gcc/gcc-8.3/0041-Add-a-recursion-limit-to-libiberty-s-demangling-code.patch new file mode 100644 index 0000000000..f3303b6858 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-8.3/0041-Add-a-recursion-limit-to-libiberty-s-demangling-code.patch | |||
@@ -0,0 +1,325 @@ | |||
1 | From e1744e11b1c2b36f91a8847b61bafb8c5e7407ae Mon Sep 17 00:00:00 2001 | ||
2 | From: nickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Fri, 7 Dec 2018 10:33:30 +0000 | ||
4 | Subject: [PATCH] Add a recursion limit to libiberty's demangling code. The | ||
5 | limit is enabled by default, but can be disabled via a new demangling option. | ||
6 | |||
7 | include * demangle.h (DMGL_NO_RECURSE_LIMIT): Define. | ||
8 | (DEMANGLE_RECURSION_LIMIT): Define | ||
9 | |||
10 | PR 87681 | ||
11 | PR 87675 | ||
12 | PR 87636 | ||
13 | PR 87350 | ||
14 | PR 87335 | ||
15 | libiberty * cp-demangle.h (struct d_info): Add recursion_level field. | ||
16 | * cp-demangle.c (d_function_type): Add recursion counter. | ||
17 | If the recursion limit is reached and the check is not disabled, | ||
18 | then return with a failure result. | ||
19 | (cplus_demangle_init_info): Initialise the recursion_level field. | ||
20 | (d_demangle_callback): If the recursion limit is enabled, check | ||
21 | for a mangled string that is so long that there is not enough | ||
22 | stack space for the local arrays. | ||
23 | * cplus-dem.c (struct work): Add recursion_level field. | ||
24 | (squangle_mop_up): Set the numb and numk fields to zero. | ||
25 | (work_stuff_copy_to_from): Handle the case where a btypevec or | ||
26 | ktypevec field is NULL. | ||
27 | (demangle_nested_args): Add recursion counter. If | ||
28 | the recursion limit is not disabled and reached, return with a | ||
29 | failure result. | ||
30 | |||
31 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266886 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
32 | |||
33 | CVE: CVE-2018-18484 | ||
34 | Upstream-Status: Backport [https://github.com/gcc-mirror/gcc/commit/03e51746ed98d9106803f6009ebd71ea670ad3b9] | ||
35 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
36 | --- | ||
37 | include/ChangeLog | 5 +++++ | ||
38 | include/demangle.h | 11 +++++++++++ | ||
39 | libiberty/ChangeLog | 23 ++++++++++++++++++++++ | ||
40 | libiberty/cp-demangle.c | 51 ++++++++++++++++++++++++++++++++++++++----------- | ||
41 | libiberty/cp-demangle.h | 3 +++ | ||
42 | libiberty/cplus-dem.c | 37 +++++++++++++++++++++++++++++++++-- | ||
43 | 6 files changed, 117 insertions(+), 13 deletions(-) | ||
44 | |||
45 | diff --git a/include/ChangeLog b/include/ChangeLog | ||
46 | index 02ab336..88b0648 100644 | ||
47 | --- a/include/ChangeLog | ||
48 | +++ b/include/ChangeLog | ||
49 | @@ -2,6 +2,11 @@ | ||
50 | |||
51 | * GCC 8.3.0 released. | ||
52 | |||
53 | +2018-12-07 Nick Clifton <nickc@redhat.com> | ||
54 | + | ||
55 | + * demangle.h (DMGL_NO_RECURSE_LIMIT): Define. | ||
56 | + (DEMANGLE_RECURSION_LIMIT): Define | ||
57 | + | ||
58 | 2018-07-26 Release Manager | ||
59 | |||
60 | * GCC 8.2.0 released. | ||
61 | diff --git a/include/demangle.h b/include/demangle.h | ||
62 | index b8d57cf..9bb8a19 100644 | ||
63 | --- a/include/demangle.h | ||
64 | +++ b/include/demangle.h | ||
65 | @@ -68,6 +68,17 @@ extern "C" { | ||
66 | /* If none of these are set, use 'current_demangling_style' as the default. */ | ||
67 | #define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST) | ||
68 | |||
69 | +/* Disable a limit on the depth of recursion in mangled strings. | ||
70 | + Note if this limit is disabled then stack exhaustion is possible when | ||
71 | + demangling pathologically complicated strings. Bug reports about stack | ||
72 | + exhaustion when the option is enabled will be rejected. */ | ||
73 | +#define DMGL_NO_RECURSE_LIMIT (1 << 18) | ||
74 | + | ||
75 | +/* If DMGL_NO_RECURSE_LIMIT is not enabled, then this is the value used as | ||
76 | + the maximum depth of recursion allowed. It should be enough for any | ||
77 | + real-world mangled name. */ | ||
78 | +#define DEMANGLE_RECURSION_LIMIT 1024 | ||
79 | + | ||
80 | /* Enumeration of possible demangling styles. | ||
81 | |||
82 | Lucid and ARM styles are still kept logically distinct, even though | ||
83 | diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog | ||
84 | index 1dd05da..2f77038 100644 | ||
85 | --- a/libiberty/ChangeLog | ||
86 | +++ b/libiberty/ChangeLog | ||
87 | @@ -9,6 +9,29 @@ | ||
88 | (simple_object_copy_lto_debug_sections): Create file in binary | ||
89 | mode. | ||
90 | |||
91 | +2018-12-07 Nick Clifton <nickc@redhat.com> | ||
92 | + | ||
93 | + PR 87681 | ||
94 | + PR 87675 | ||
95 | + PR 87636 | ||
96 | + PR 87350 | ||
97 | + PR 87335 | ||
98 | + * cp-demangle.h (struct d_info): Add recursion_level field. | ||
99 | + * cp-demangle.c (d_function_type): Add recursion counter. | ||
100 | + If the recursion limit is reached and the check is not disabled, | ||
101 | + then return with a failure result. | ||
102 | + (cplus_demangle_init_info): Initialise the recursion_level field. | ||
103 | + (d_demangle_callback): If the recursion limit is enabled, check | ||
104 | + for a mangled string that is so long that there is not enough | ||
105 | + stack space for the local arrays. | ||
106 | + * cplus-dem.c (struct work): Add recursion_level field. | ||
107 | + (squangle_mop_up): Set the numb and numk fields to zero. | ||
108 | + (work_stuff_copy_to_from): Handle the case where a btypevec or | ||
109 | + ktypevec field is NULL. | ||
110 | + (demangle_nested_args): Add recursion counter. If | ||
111 | + the recursion limit is not disabled and reached, return with a | ||
112 | + failure result. | ||
113 | + | ||
114 | 2018-07-26 Release Manager | ||
115 | |||
116 | * GCC 8.2.0 released. | ||
117 | diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c | ||
118 | index 3f2a097..c374e46 100644 | ||
119 | --- a/libiberty/cp-demangle.c | ||
120 | +++ b/libiberty/cp-demangle.c | ||
121 | @@ -2843,21 +2843,35 @@ d_ref_qualifier (struct d_info *di, struct demangle_component *sub) | ||
122 | static struct demangle_component * | ||
123 | d_function_type (struct d_info *di) | ||
124 | { | ||
125 | - struct demangle_component *ret; | ||
126 | + struct demangle_component *ret = NULL; | ||
127 | |||
128 | - if (! d_check_char (di, 'F')) | ||
129 | - return NULL; | ||
130 | - if (d_peek_char (di) == 'Y') | ||
131 | + if ((di->options & DMGL_NO_RECURSE_LIMIT) == 0) | ||
132 | { | ||
133 | - /* Function has C linkage. We don't print this information. | ||
134 | - FIXME: We should print it in verbose mode. */ | ||
135 | - d_advance (di, 1); | ||
136 | + if (di->recursion_level > DEMANGLE_RECURSION_LIMIT) | ||
137 | + /* FIXME: There ought to be a way to report | ||
138 | + that the recursion limit has been reached. */ | ||
139 | + return NULL; | ||
140 | + | ||
141 | + di->recursion_level ++; | ||
142 | } | ||
143 | - ret = d_bare_function_type (di, 1); | ||
144 | - ret = d_ref_qualifier (di, ret); | ||
145 | |||
146 | - if (! d_check_char (di, 'E')) | ||
147 | - return NULL; | ||
148 | + if (d_check_char (di, 'F')) | ||
149 | + { | ||
150 | + if (d_peek_char (di) == 'Y') | ||
151 | + { | ||
152 | + /* Function has C linkage. We don't print this information. | ||
153 | + FIXME: We should print it in verbose mode. */ | ||
154 | + d_advance (di, 1); | ||
155 | + } | ||
156 | + ret = d_bare_function_type (di, 1); | ||
157 | + ret = d_ref_qualifier (di, ret); | ||
158 | + | ||
159 | + if (! d_check_char (di, 'E')) | ||
160 | + ret = NULL; | ||
161 | + } | ||
162 | + | ||
163 | + if ((di->options & DMGL_NO_RECURSE_LIMIT) == 0) | ||
164 | + di->recursion_level --; | ||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | @@ -6188,6 +6202,7 @@ cplus_demangle_init_info (const char *mangled, int options, size_t len, | ||
169 | di->expansion = 0; | ||
170 | di->is_expression = 0; | ||
171 | di->is_conversion = 0; | ||
172 | + di->recursion_level = 0; | ||
173 | } | ||
174 | |||
175 | /* Internal implementation for the demangler. If MANGLED is a g++ v3 ABI | ||
176 | @@ -6227,6 +6242,20 @@ d_demangle_callback (const char *mangled, int options, | ||
177 | |||
178 | cplus_demangle_init_info (mangled, options, strlen (mangled), &di); | ||
179 | |||
180 | + /* PR 87675 - Check for a mangled string that is so long | ||
181 | + that we do not have enough stack space to demangle it. */ | ||
182 | + if (((options & DMGL_NO_RECURSE_LIMIT) == 0) | ||
183 | + /* This check is a bit arbitrary, since what we really want to do is to | ||
184 | + compare the sizes of the di.comps and di.subs arrays against the | ||
185 | + amount of stack space remaining. But there is no portable way to do | ||
186 | + this, so instead we use the recursion limit as a guide to the maximum | ||
187 | + size of the arrays. */ | ||
188 | + && (unsigned long) di.num_comps > DEMANGLE_RECURSION_LIMIT) | ||
189 | + { | ||
190 | + /* FIXME: We need a way to indicate that a stack limit has been reached. */ | ||
191 | + return 0; | ||
192 | + } | ||
193 | + | ||
194 | { | ||
195 | #ifdef CP_DYNAMIC_ARRAYS | ||
196 | __extension__ struct demangle_component comps[di.num_comps]; | ||
197 | diff --git a/libiberty/cp-demangle.h b/libiberty/cp-demangle.h | ||
198 | index 51b8a24..d87a830 100644 | ||
199 | --- a/libiberty/cp-demangle.h | ||
200 | +++ b/libiberty/cp-demangle.h | ||
201 | @@ -122,6 +122,9 @@ struct d_info | ||
202 | /* Non-zero if we are parsing the type operand of a conversion | ||
203 | operator, but not when in an expression. */ | ||
204 | int is_conversion; | ||
205 | + /* If DMGL_NO_RECURSE_LIMIT is not active then this is set to | ||
206 | + the current recursion level. */ | ||
207 | + unsigned int recursion_level; | ||
208 | }; | ||
209 | |||
210 | /* To avoid running past the ending '\0', don't: | ||
211 | diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c | ||
212 | index 6d58bd8..8b9646f 100644 | ||
213 | --- a/libiberty/cplus-dem.c | ||
214 | +++ b/libiberty/cplus-dem.c | ||
215 | @@ -146,6 +146,7 @@ struct work_stuff | ||
216 | int *proctypevec; /* Indices of currently processed remembered typevecs. */ | ||
217 | int proctypevec_size; | ||
218 | int nproctypes; | ||
219 | + unsigned int recursion_level; | ||
220 | }; | ||
221 | |||
222 | #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) | ||
223 | @@ -1292,12 +1293,14 @@ squangle_mop_up (struct work_stuff *work) | ||
224 | free ((char *) work -> btypevec); | ||
225 | work->btypevec = NULL; | ||
226 | work->bsize = 0; | ||
227 | + work->numb = 0; | ||
228 | } | ||
229 | if (work -> ktypevec != NULL) | ||
230 | { | ||
231 | free ((char *) work -> ktypevec); | ||
232 | work->ktypevec = NULL; | ||
233 | work->ksize = 0; | ||
234 | + work->numk = 0; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | @@ -1331,8 +1334,15 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) | ||
239 | |||
240 | for (i = 0; i < from->numk; i++) | ||
241 | { | ||
242 | - int len = strlen (from->ktypevec[i]) + 1; | ||
243 | + int len; | ||
244 | + | ||
245 | + if (from->ktypevec[i] == NULL) | ||
246 | + { | ||
247 | + to->ktypevec[i] = NULL; | ||
248 | + continue; | ||
249 | + } | ||
250 | |||
251 | + len = strlen (from->ktypevec[i]) + 1; | ||
252 | to->ktypevec[i] = XNEWVEC (char, len); | ||
253 | memcpy (to->ktypevec[i], from->ktypevec[i], len); | ||
254 | } | ||
255 | @@ -1342,8 +1352,15 @@ work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) | ||
256 | |||
257 | for (i = 0; i < from->numb; i++) | ||
258 | { | ||
259 | - int len = strlen (from->btypevec[i]) + 1; | ||
260 | + int len; | ||
261 | + | ||
262 | + if (from->btypevec[i] == NULL) | ||
263 | + { | ||
264 | + to->btypevec[i] = NULL; | ||
265 | + continue; | ||
266 | + } | ||
267 | |||
268 | + len = strlen (from->btypevec[i]) + 1; | ||
269 | to->btypevec[i] = XNEWVEC (char , len); | ||
270 | memcpy (to->btypevec[i], from->btypevec[i], len); | ||
271 | } | ||
272 | @@ -1401,6 +1418,7 @@ delete_non_B_K_work_stuff (struct work_stuff *work) | ||
273 | |||
274 | free ((char*) work->tmpl_argvec); | ||
275 | work->tmpl_argvec = NULL; | ||
276 | + work->ntmpl_args = 0; | ||
277 | } | ||
278 | if (work->previous_argument) | ||
279 | { | ||
280 | @@ -4477,6 +4495,7 @@ remember_Btype (struct work_stuff *work, const char *start, | ||
281 | } | ||
282 | |||
283 | /* Lose all the info related to B and K type codes. */ | ||
284 | + | ||
285 | static void | ||
286 | forget_B_and_K_types (struct work_stuff *work) | ||
287 | { | ||
288 | @@ -4502,6 +4521,7 @@ forget_B_and_K_types (struct work_stuff *work) | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | + | ||
293 | /* Forget the remembered types, but not the type vector itself. */ | ||
294 | |||
295 | static void | ||
296 | @@ -4696,6 +4716,16 @@ demangle_nested_args (struct work_stuff *work, const char **mangled, | ||
297 | int result; | ||
298 | int saved_nrepeats; | ||
299 | |||
300 | + if ((work->options & DMGL_NO_RECURSE_LIMIT) == 0) | ||
301 | + { | ||
302 | + if (work->recursion_level > DEMANGLE_RECURSION_LIMIT) | ||
303 | + /* FIXME: There ought to be a way to report | ||
304 | + that the recursion limit has been reached. */ | ||
305 | + return 0; | ||
306 | + | ||
307 | + work->recursion_level ++; | ||
308 | + } | ||
309 | + | ||
310 | /* The G++ name-mangling algorithm does not remember types on nested | ||
311 | argument lists, unless -fsquangling is used, and in that case the | ||
312 | type vector updated by remember_type is not used. So, we turn | ||
313 | @@ -4722,6 +4752,9 @@ demangle_nested_args (struct work_stuff *work, const char **mangled, | ||
314 | --work->forgetting_types; | ||
315 | work->nrepeats = saved_nrepeats; | ||
316 | |||
317 | + if ((work->options & DMGL_NO_RECURSE_LIMIT) == 0) | ||
318 | + --work->recursion_level; | ||
319 | + | ||
320 | return result; | ||
321 | } | ||
322 | |||
323 | -- | ||
324 | 2.7.4 | ||
325 | |||