summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorAnuj Mittal <anuj.mittal@intel.com>2019-04-29 14:26:33 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-04-30 12:05:23 +0100
commite2cc220b0aa9725d673b16293b73d6b470fdf4d4 (patch)
tree6be9ec37a67bc5baf78bc1f634609eb6dd1883d9 /meta
parente7c2bc67b51aff57fe3d6c1caf22f457565deede (diff)
downloadpoky-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.inc1
-rw-r--r--meta/recipes-devtools/gcc/gcc-8.3/0041-Add-a-recursion-limit-to-libiberty-s-demangling-code.patch325
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"
75SRC_URI[md5sum] = "65b210b4bfe7e060051f799e0f994896" 76SRC_URI[md5sum] = "65b210b4bfe7e060051f799e0f994896"
76SRC_URI[sha256sum] = "64baadfe6cc0f4947a84cb12d7f0dfaf45bb58b7e92461639596c21e02d97d2c" 77SRC_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 @@
1From e1744e11b1c2b36f91a8847b61bafb8c5e7407ae Mon Sep 17 00:00:00 2001
2From: nickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Fri, 7 Dec 2018 10:33:30 +0000
4Subject: [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
7include * 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
15libiberty * 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
31git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266886 138bc75d-0d04-0410-961f-82ee72b054a4
32
33CVE: CVE-2018-18484
34Upstream-Status: Backport [https://github.com/gcc-mirror/gcc/commit/03e51746ed98d9106803f6009ebd71ea670ad3b9]
35Signed-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
45diff --git a/include/ChangeLog b/include/ChangeLog
46index 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.
61diff --git a/include/demangle.h b/include/demangle.h
62index 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
83diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
84index 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.
117diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
118index 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];
197diff --git a/libiberty/cp-demangle.h b/libiberty/cp-demangle.h
198index 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:
211diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
212index 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--
3242.7.4
325