summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Kuster <akuster@mvista.com>2018-08-07 02:21:59 (GMT)
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-08-15 09:22:45 (GMT)
commit8011a1aed9287f9c4c108c7ad00d1f8588aedade (patch)
treee409dfbf294196e918422be4fb126307a83f764b
parent9e7dc232e714189a8dc1233bd8c956891c79e5eb (diff)
downloadpoky-8011a1aed9287f9c4c108c7ad00d1f8588aedade.tar.gz
binutls: Security fix for CVE-2017-15024
Affects: <= 2.29.1 (From OE-Core rev: 349b3cfb39c76304e351481899de9f72e4f1295b) Signed-off-by: Armin Kuster <akuster@mvista.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.29.1.inc1
-rw-r--r--meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch227
2 files changed, 228 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.29.1.inc b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
index caff121..3a56e97 100644
--- a/meta/recipes-devtools/binutils/binutils-2.29.1.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.29.1.inc
@@ -47,6 +47,7 @@ SRC_URI = "\
47 file://CVE-2017-15021.patch \ 47 file://CVE-2017-15021.patch \
48 file://CVE-2017-15022.patch \ 48 file://CVE-2017-15022.patch \
49 file://CVE-2017-15023.patch \ 49 file://CVE-2017-15023.patch \
50 file://CVE-2017-15024.patch \
50" 51"
51S = "${WORKDIR}/git" 52S = "${WORKDIR}/git"
52 53
diff --git a/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch b/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch
new file mode 100644
index 0000000..53b072e
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/CVE-2017-15024.patch
@@ -0,0 +1,227 @@
1From 52a93b95ec0771c97e26f0bb28630a271a667bd2 Mon Sep 17 00:00:00 2001
2From: Alan Modra <amodra@gmail.com>
3Date: Sun, 24 Sep 2017 14:37:16 +0930
4Subject: [PATCH] PR22187, infinite loop in find_abstract_instance_name
5
6This patch prevents the simple case of infinite recursion in
7find_abstract_instance_name by ensuring that the attributes being
8processed are not the same as the previous call.
9
10The patch also does a little cleanup, and leaves in place some changes
11to the nested_funcs array that I made when I wrongly thought looping
12might occur in scan_unit_for_symbols.
13
14 PR 22187
15 * dwarf2.c (find_abstract_instance_name): Add orig_info_ptr and
16 pname param. Return status. Make name const. Don't abort,
17 return an error. Formatting. Exit if current info_ptr matches
18 orig_info_ptr. Update callers.
19 (scan_unit_for_symbols): Start at nesting_level of zero. Make
20 nested_funcs an array of structs for extensibility. Formatting.
21
22Upstream-Status: Backport
23Affects: <= 2.29.1
24CVE: CVE-2017-15024
25Signed-off-by: Armin Kuster <akuster@mvista.com>
26
27---
28 bfd/ChangeLog | 10 ++++++++
29 bfd/dwarf2.c | 76 +++++++++++++++++++++++++++++++++++++++--------------------
30 2 files changed, 61 insertions(+), 25 deletions(-)
31
32Index: git/bfd/dwarf2.c
33===================================================================
34--- git.orig/bfd/dwarf2.c
35+++ git/bfd/dwarf2.c
36@@ -2823,9 +2823,11 @@ lookup_symbol_in_variable_table (struct
37 return FALSE;
38 }
39
40-static char *
41+static bfd_boolean
42 find_abstract_instance_name (struct comp_unit *unit,
43+ bfd_byte *orig_info_ptr,
44 struct attribute *attr_ptr,
45+ const char **pname,
46 bfd_boolean *is_linkage)
47 {
48 bfd *abfd = unit->abfd;
49@@ -2835,7 +2837,7 @@ find_abstract_instance_name (struct comp
50 struct abbrev_info *abbrev;
51 bfd_uint64_t die_ref = attr_ptr->u.val;
52 struct attribute attr;
53- char *name = NULL;
54+ const char *name = NULL;
55
56 /* DW_FORM_ref_addr can reference an entry in a different CU. It
57 is an offset from the .debug_info section, not the current CU. */
58@@ -2844,7 +2846,12 @@ find_abstract_instance_name (struct comp
59 /* We only support DW_FORM_ref_addr within the same file, so
60 any relocations should be resolved already. */
61 if (!die_ref)
62- abort ();
63+ {
64+ _bfd_error_handler
65+ (_("Dwarf Error: Abstract instance DIE ref zero."));
66+ bfd_set_error (bfd_error_bad_value);
67+ return FALSE;
68+ }
69
70 info_ptr = unit->sec_info_ptr + die_ref;
71 info_ptr_end = unit->end_ptr;
72@@ -2879,9 +2886,10 @@ find_abstract_instance_name (struct comp
73 _bfd_error_handler
74 (_("Dwarf Error: Unable to read alt ref %u."), die_ref);
75 bfd_set_error (bfd_error_bad_value);
76- return NULL;
77+ return FALSE;
78 }
79- info_ptr_end = unit->stash->alt_dwarf_info_buffer + unit->stash->alt_dwarf_info_size;
80+ info_ptr_end = (unit->stash->alt_dwarf_info_buffer
81+ + unit->stash->alt_dwarf_info_size);
82
83 /* FIXME: Do we need to locate the correct CU, in a similar
84 fashion to the code in the DW_FORM_ref_addr case above ? */
85@@ -2904,6 +2912,7 @@ find_abstract_instance_name (struct comp
86 _bfd_error_handler
87 (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number);
88 bfd_set_error (bfd_error_bad_value);
89+ return FALSE;
90 }
91 else
92 {
93@@ -2913,6 +2922,15 @@ find_abstract_instance_name (struct comp
94 info_ptr, info_ptr_end);
95 if (info_ptr == NULL)
96 break;
97+ /* It doesn't ever make sense for DW_AT_specification to
98+ refer to the same DIE. Stop simple recursion. */
99+ if (info_ptr == orig_info_ptr)
100+ {
101+ _bfd_error_handler
102+ (_("Dwarf Error: Abstract instance recursion detected."));
103+ bfd_set_error (bfd_error_bad_value);
104+ return FALSE;
105+ }
106 switch (attr.name)
107 {
108 case DW_AT_name:
109@@ -2926,7 +2944,9 @@ find_abstract_instance_name (struct comp
110 }
111 break;
112 case DW_AT_specification:
113- name = find_abstract_instance_name (unit, &attr, is_linkage);
114+ if (!find_abstract_instance_name (unit, info_ptr, &attr,
115+ pname, is_linkage))
116+ return FALSE;
117 break;
118 case DW_AT_linkage_name:
119 case DW_AT_MIPS_linkage_name:
120@@ -2944,7 +2964,8 @@ find_abstract_instance_name (struct comp
121 }
122 }
123 }
124- return name;
125+ *pname = name;
126+ return TRUE;
127 }
128
129 static bfd_boolean
130@@ -3005,20 +3026,22 @@ scan_unit_for_symbols (struct comp_unit
131 bfd *abfd = unit->abfd;
132 bfd_byte *info_ptr = unit->first_child_die_ptr;
133 bfd_byte *info_ptr_end = unit->stash->info_ptr_end;
134- int nesting_level = 1;
135- struct funcinfo **nested_funcs;
136+ int nesting_level = 0;
137+ struct nest_funcinfo {
138+ struct funcinfo *func;
139+ } *nested_funcs;
140 int nested_funcs_size;
141
142 /* Maintain a stack of in-scope functions and inlined functions, which we
143 can use to set the caller_func field. */
144 nested_funcs_size = 32;
145- nested_funcs = (struct funcinfo **)
146- bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
147+ nested_funcs = (struct nest_funcinfo *)
148+ bfd_malloc (nested_funcs_size * sizeof (*nested_funcs));
149 if (nested_funcs == NULL)
150 return FALSE;
151- nested_funcs[nesting_level] = 0;
152+ nested_funcs[nesting_level].func = 0;
153
154- while (nesting_level)
155+ while (nesting_level >= 0)
156 {
157 unsigned int abbrev_number, bytes_read, i;
158 struct abbrev_info *abbrev;
159@@ -3076,13 +3099,13 @@ scan_unit_for_symbols (struct comp_unit
160 BFD_ASSERT (!unit->cached);
161
162 if (func->tag == DW_TAG_inlined_subroutine)
163- for (i = nesting_level - 1; i >= 1; i--)
164- if (nested_funcs[i])
165+ for (i = nesting_level; i-- != 0; )
166+ if (nested_funcs[i].func)
167 {
168- func->caller_func = nested_funcs[i];
169+ func->caller_func = nested_funcs[i].func;
170 break;
171 }
172- nested_funcs[nesting_level] = func;
173+ nested_funcs[nesting_level].func = func;
174 }
175 else
176 {
177@@ -3102,12 +3125,13 @@ scan_unit_for_symbols (struct comp_unit
178 }
179
180 /* No inline function in scope at this nesting level. */
181- nested_funcs[nesting_level] = 0;
182+ nested_funcs[nesting_level].func = 0;
183 }
184
185 for (i = 0; i < abbrev->num_attrs; ++i)
186 {
187- info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr, info_ptr_end);
188+ info_ptr = read_attribute (&attr, &abbrev->attrs[i],
189+ unit, info_ptr, info_ptr_end);
190 if (info_ptr == NULL)
191 goto fail;
192
193@@ -3126,8 +3150,10 @@ scan_unit_for_symbols (struct comp_unit
194
195 case DW_AT_abstract_origin:
196 case DW_AT_specification:
197- func->name = find_abstract_instance_name (unit, &attr,
198- &func->is_linkage);
199+ if (!find_abstract_instance_name (unit, info_ptr, &attr,
200+ &func->name,
201+ &func->is_linkage))
202+ goto fail;
203 break;
204
205 case DW_AT_name:
206@@ -3254,17 +3280,17 @@ scan_unit_for_symbols (struct comp_unit
207
208 if (nesting_level >= nested_funcs_size)
209 {
210- struct funcinfo **tmp;
211+ struct nest_funcinfo *tmp;
212
213 nested_funcs_size *= 2;
214- tmp = (struct funcinfo **)
215+ tmp = (struct nest_funcinfo *)
216 bfd_realloc (nested_funcs,
217- nested_funcs_size * sizeof (struct funcinfo *));
218+ nested_funcs_size * sizeof (*nested_funcs));
219 if (tmp == NULL)
220 goto fail;
221 nested_funcs = tmp;
222 }
223- nested_funcs[nesting_level] = 0;
224+ nested_funcs[nesting_level].func = 0;
225 }
226 }
227