summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils
diff options
context:
space:
mode:
authorpgowda <pgowda.cve@gmail.com>2022-09-21 23:09:17 +0530
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-09-22 12:11:49 +0100
commit72d141568694ac4c2f9ac0919a4c791754fdb4d2 (patch)
tree56a679750c3723b41b1c687662be0d0212ca44f2 /meta/recipes-devtools/binutils
parent6505dd4ec25459c59f8c8b323058063bff81cb26 (diff)
downloadpoky-72d141568694ac4c2f9ac0919a4c791754fdb4d2.tar.gz
binutils : Fix CVE-2022-38128
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f07c08e115e27cddf5a0030dc6332bbee1bd9c6a] Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe] Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff] (From OE-Core rev: b9348a0937185a14dfb5e5be4f4269c965541769) Signed-off-by: pgowda <pgowda.cve@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/binutils')
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.39.inc3
-rw-r--r--meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch350
-rw-r--r--meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch536
-rw-r--r--meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch95
4 files changed, 984 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.39.inc b/meta/recipes-devtools/binutils/binutils-2.39.inc
index e4fdb73243..b040e57037 100644
--- a/meta/recipes-devtools/binutils/binutils-2.39.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.39.inc
@@ -32,6 +32,9 @@ SRC_URI = "\
32 file://0011-Check-for-clang-before-checking-gcc-version.patch \ 32 file://0011-Check-for-clang-before-checking-gcc-version.patch \
33 file://0012-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch \ 33 file://0012-Only-generate-an-RPATH-entry-if-LD_RUN_PATH-is-not-e.patch \
34 file://0013-CVE-2022-38533.patch \ 34 file://0013-CVE-2022-38533.patch \
35 file://0014-CVE-2022-38128-1.patch \
36 file://0014-CVE-2022-38128-2.patch \
37 file://0014-CVE-2022-38128-3.patch \
35" 38"
36S = "${WORKDIR}/git" 39S = "${WORKDIR}/git"
37# Already in 2.39 branch 40# Already in 2.39 branch
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch
new file mode 100644
index 0000000000..0a490d86b3
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-1.patch
@@ -0,0 +1,350 @@
1From f07c08e115e27cddf5a0030dc6332bbee1bd9c6a Mon Sep 17 00:00:00 2001
2From: Alan Modra <amodra@gmail.com>
3Date: Thu, 21 Jul 2022 08:38:14 +0930
4Subject: [PATCH] binutils/dwarf.c: abbrev caching
5
6I'm inclined to think that abbrev caching is counter-productive. The
7time taken to search the list of abbrevs converted to internal form is
8non-zero, and it's easy to decode the raw abbrevs. It's especially
9silly to cache empty lists of decoded abbrevs (happens with zero
10padding in .debug_abbrev), or abbrevs as they are displayed when there
11is no further use of those abbrevs. This patch stops caching in those
12cases.
13
14 * dwarf.c (record_abbrev_list_for_cu): Add free_list param.
15 Put abbrevs on abbrev_lists here.
16 (new_abbrev_list): Delete function.
17 (process_abbrev_set): Return newly allocated list. Move
18 abbrev base, offset and size checking to..
19 (find_and_process_abbrev_set): ..here, new function. Handle
20 lookup of cached abbrevs here, and calculate start and end
21 for process_abbrev_set. Return free_list if newly alloc'd.
22 (process_debug_info): Consolidate cached list lookup, new list
23 alloc and processing into find_and_process_abbrev_set call.
24 Free list when not cached.
25 (display_debug_abbrev): Similarly.
26
27Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=f07c08e115e27cddf5a0030dc6332bbee1bd9c6a]
28
29Signed-off-by: Pgowda <pgowda.cve@gmail.com>
30---
31 binutils/dwarf.c | 208 +++++++++++++++++++++++++----------------------
32 1 file changed, 110 insertions(+), 98 deletions(-)
33
34diff --git a/binutils/dwarf.c b/binutils/dwarf.c
35index 267ed3bb382..2fc352f74c5 100644
36--- a/binutils/dwarf.c
37+++ b/binutils/dwarf.c
38@@ -882,8 +882,15 @@ static unsigned long next_free_abbrev_m
39 #define ABBREV_MAP_ENTRIES_INCREMENT 8
40
41 static void
42-record_abbrev_list_for_cu (dwarf_vma start, dwarf_vma end, abbrev_list * list)
43+record_abbrev_list_for_cu (dwarf_vma start, dwarf_vma end,
44+ abbrev_list *list, abbrev_list *free_list)
45 {
46+ if (free_list != NULL)
47+ {
48+ list->next = abbrev_lists;
49+ abbrev_lists = list;
50+ }
51+
52 if (cu_abbrev_map == NULL)
53 {
54 num_abbrev_map_entries = INITIAL_NUM_ABBREV_MAP_ENTRIES;
55@@ -936,20 +943,6 @@ free_all_abbrevs (void)
56 }
57
58 static abbrev_list *
59-new_abbrev_list (dwarf_vma abbrev_base, dwarf_vma abbrev_offset)
60-{
61- abbrev_list * list = (abbrev_list *) xcalloc (sizeof * list, 1);
62-
63- list->abbrev_base = abbrev_base;
64- list->abbrev_offset = abbrev_offset;
65-
66- list->next = abbrev_lists;
67- abbrev_lists = list;
68-
69- return list;
70-}
71-
72-static abbrev_list *
73 find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base,
74 dwarf_vma abbrev_offset)
75 {
76@@ -966,7 +959,7 @@ find_abbrev_list_by_abbrev_offset (dwarf
77 /* Find the abbreviation map for the CU that includes OFFSET.
78 OFFSET is an absolute offset from the start of the .debug_info section. */
79 /* FIXME: This function is going to slow down readelf & objdump.
80- Consider using a better algorithm to mitigate this effect. */
81+ Not caching abbrevs is likely the answer. */
82
83 static abbrev_map *
84 find_abbrev_map_by_offset (dwarf_vma offset)
85@@ -1033,40 +1026,18 @@ add_abbrev_attr (unsigned long attrib
86 list->last_abbrev->last_attr = attr;
87 }
88
89-/* Processes the (partial) contents of a .debug_abbrev section.
90- Returns NULL if the end of the section was encountered.
91- Returns the address after the last byte read if the end of
92- an abbreviation set was found. */
93+/* Return processed (partial) contents of a .debug_abbrev section.
94+ Returns NULL on errors. */
95
96-static unsigned char *
97+static abbrev_list *
98 process_abbrev_set (struct dwarf_section *section,
99- dwarf_vma abbrev_base,
100- dwarf_vma abbrev_size,
101- dwarf_vma abbrev_offset,
102- abbrev_list *list)
103+ unsigned char *start,
104+ unsigned char *end)
105 {
106- if (abbrev_base >= section->size
107- || abbrev_size > section->size - abbrev_base)
108- {
109- /* PR 17531: file:4bcd9ce9. */
110- warn (_("Debug info is corrupted, abbrev size (%lx) is larger than "
111- "abbrev section size (%lx)\n"),
112- (unsigned long) (abbrev_base + abbrev_size),
113- (unsigned long) section->size);
114- return NULL;
115- }
116- if (abbrev_offset >= abbrev_size)
117- {
118- warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than "
119- "abbrev section size (%lx)\n"),
120- (unsigned long) abbrev_offset,
121- (unsigned long) abbrev_size);
122- return NULL;
123- }
124+ abbrev_list *list = xmalloc (sizeof (*list));
125+ list->first_abbrev = NULL;
126+ list->last_abbrev = NULL;
127
128- unsigned char *start = section->start + abbrev_base;
129- unsigned char *end = start + abbrev_size;
130- start += abbrev_offset;
131 while (start < end)
132 {
133 unsigned long entry;
134@@ -1079,14 +1050,18 @@ process_abbrev_set (struct dwarf_section
135 /* A single zero is supposed to end the set according
136 to the standard. If there's more, then signal that to
137 the caller. */
138- if (start == end)
139- return NULL;
140- if (entry == 0)
141- return start;
142+ if (start == end || entry == 0)
143+ {
144+ list->start_of_next_abbrevs = start != end ? start : NULL;
145+ return list;
146+ }
147
148 READ_ULEB (tag, start, end);
149 if (start == end)
150- return NULL;
151+ {
152+ free (list);
153+ return NULL;
154+ }
155
156 children = *start++;
157
158@@ -1121,9 +1096,67 @@ process_abbrev_set (struct dwarf_section
159 /* Report the missing single zero which ends the section. */
160 error (_(".debug_abbrev section not zero terminated\n"));
161
162+ free (list);
163 return NULL;
164 }
165
166+/* Return a sequence of abbrevs in SECTION starting at ABBREV_BASE
167+ plus ABBREV_OFFSET and finishing at ABBREV_BASE + ABBREV_SIZE.
168+ If FREE_LIST is non-NULL search the already decoded abbrevs on
169+ abbrev_lists first and if found set *FREE_LIST to NULL. If
170+ searching doesn't find a matching abbrev, set *FREE_LIST to the
171+ newly allocated list. If FREE_LIST is NULL, no search is done and
172+ the returned abbrev_list is always newly allocated. */
173+
174+static abbrev_list *
175+find_and_process_abbrev_set (struct dwarf_section *section,
176+ dwarf_vma abbrev_base,
177+ dwarf_vma abbrev_size,
178+ dwarf_vma abbrev_offset,
179+ abbrev_list **free_list)
180+{
181+ if (free_list)
182+ *free_list = NULL;
183+
184+ if (abbrev_base >= section->size
185+ || abbrev_size > section->size - abbrev_base)
186+ {
187+ /* PR 17531: file:4bcd9ce9. */
188+ warn (_("Debug info is corrupted, abbrev size (%lx) is larger than "
189+ "abbrev section size (%lx)\n"),
190+ (unsigned long) (abbrev_base + abbrev_size),
191+ (unsigned long) section->size);
192+ return NULL;
193+ }
194+ if (abbrev_offset >= abbrev_size)
195+ {
196+ warn (_("Debug info is corrupted, abbrev offset (%lx) is larger than "
197+ "abbrev section size (%lx)\n"),
198+ (unsigned long) abbrev_offset,
199+ (unsigned long) abbrev_size);
200+ return NULL;
201+ }
202+
203+ unsigned char *start = section->start + abbrev_base + abbrev_offset;
204+ unsigned char *end = section->start + abbrev_base + abbrev_size;
205+ abbrev_list *list = NULL;
206+ if (free_list)
207+ list = find_abbrev_list_by_abbrev_offset (abbrev_base, abbrev_offset);
208+ if (list == NULL)
209+ {
210+ list = process_abbrev_set (section, start, end);
211+ if (list)
212+ {
213+ list->abbrev_base = abbrev_base;
214+ list->abbrev_offset = abbrev_offset;
215+ list->next = NULL;
216+ }
217+ if (free_list)
218+ *free_list = list;
219+ }
220+ return list;
221+}
222+
223 static const char *
224 get_TAG_name (unsigned long tag)
225 {
226@@ -3670,7 +3703,6 @@ process_debug_info (struct dwarf_section
227 dwarf_vma cu_offset;
228 unsigned int offset_size;
229 struct cu_tu_set * this_set;
230- abbrev_list * list;
231 unsigned char *end_cu;
232
233 hdrptr = start;
234@@ -3726,22 +3758,18 @@ process_debug_info (struct dwarf_section
235 abbrev_size = this_set->section_sizes [DW_SECT_ABBREV];
236 }
237
238- list = find_abbrev_list_by_abbrev_offset (abbrev_base,
239- compunit.cu_abbrev_offset);
240- if (list == NULL)
241- {
242- unsigned char * next;
243-
244- list = new_abbrev_list (abbrev_base,
245- compunit.cu_abbrev_offset);
246- next = process_abbrev_set (&debug_displays[abbrev_sec].section,
247- abbrev_base, abbrev_size,
248- compunit.cu_abbrev_offset, list);
249- list->start_of_next_abbrevs = next;
250- }
251-
252+ abbrev_list *list;
253+ abbrev_list *free_list;
254+ list = find_and_process_abbrev_set (&debug_displays[abbrev_sec].section,
255+ abbrev_base, abbrev_size,
256+ compunit.cu_abbrev_offset,
257+ &free_list);
258 start = end_cu;
259- record_abbrev_list_for_cu (cu_offset, start - section_begin, list);
260+ if (list != NULL && list->first_abbrev != NULL)
261+ record_abbrev_list_for_cu (cu_offset, start - section_begin,
262+ list, free_list);
263+ else if (free_list != NULL)
264+ free_abbrev_list (free_list);
265 }
266
267 for (start = section_begin, unit = 0; start < end; unit++)
268@@ -3757,7 +3785,6 @@ process_debug_info (struct dwarf_section
269 struct cu_tu_set *this_set;
270 dwarf_vma abbrev_base;
271 size_t abbrev_size;
272- abbrev_list * list = NULL;
273 unsigned char *end_cu;
274
275 hdrptr = start;
276@@ -3936,20 +3963,10 @@ process_debug_info (struct dwarf_section
277 }
278
279 /* Process the abbrevs used by this compilation unit. */
280- list = find_abbrev_list_by_abbrev_offset (abbrev_base,
281- compunit.cu_abbrev_offset);
282- if (list == NULL)
283- {
284- unsigned char *next;
285-
286- list = new_abbrev_list (abbrev_base,
287- compunit.cu_abbrev_offset);
288- next = process_abbrev_set (&debug_displays[abbrev_sec].section,
289- abbrev_base, abbrev_size,
290- compunit.cu_abbrev_offset, list);
291- list->start_of_next_abbrevs = next;
292- }
293-
294+ abbrev_list *list;
295+ list = find_and_process_abbrev_set (&debug_displays[abbrev_sec].section,
296+ abbrev_base, abbrev_size,
297+ compunit.cu_abbrev_offset, NULL);
298 level = 0;
299 last_level = level;
300 saved_level = -1;
301@@ -4128,6 +4145,8 @@ process_debug_info (struct dwarf_section
302 if (entry->children)
303 ++level;
304 }
305+ if (list != NULL)
306+ free_abbrev_list (list);
307 }
308
309 /* Set num_debug_info_entries here so that it can be used to check if
310@@ -6353,24 +6372,15 @@ display_debug_abbrev (struct dwarf_secti
311
312 do
313 {
314- abbrev_list * list;
315- dwarf_vma offset;
316-
317- offset = start - section->start;
318- list = find_abbrev_list_by_abbrev_offset (0, offset);
319+ dwarf_vma offset = start - section->start;
320+ abbrev_list *list = find_and_process_abbrev_set (section, 0,
321+ section->size, offset,
322+ NULL);
323 if (list == NULL)
324- {
325- list = new_abbrev_list (0, offset);
326- start = process_abbrev_set (section, 0, section->size, offset, list);
327- list->start_of_next_abbrevs = start;
328- }
329- else
330- start = list->start_of_next_abbrevs;
331-
332- if (list->first_abbrev == NULL)
333- continue;
334+ break;
335
336- printf (_(" Number TAG (0x%lx)\n"), (long) offset);
337+ if (list->first_abbrev)
338+ printf (_(" Number TAG (0x%lx)\n"), (long) offset);
339
340 for (entry = list->first_abbrev; entry; entry = entry->next)
341 {
342@@ -6391,6 +6401,8 @@ display_debug_abbrev (struct dwarf_secti
343 putchar ('\n');
344 }
345 }
346+ start = list->start_of_next_abbrevs;
347+ free_abbrev_list (list);
348 }
349 while (start);
350
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch
new file mode 100644
index 0000000000..e30b4d86e1
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-2.patch
@@ -0,0 +1,536 @@
1From 175b91507b83ad42607d2f6dadaf55b7b511bdbe Mon Sep 17 00:00:00 2001
2From: Alan Modra <amodra@gmail.com>
3Date: Wed, 20 Jul 2022 18:28:50 +0930
4Subject: [PATCH] miscellaneous dwarf.c tidies
5
6 * dwarf.c: Leading and trailing whitespace fixes.
7 (free_abbrev_list): New function.
8 (free_all_abbrevs): Use the above. Free cu_abbrev_map here too.
9 (process_abbrev_set): Print actual section name on error.
10 (get_type_abbrev_from_form): Add overflow check.
11 (free_debug_memory): Don't free cu_abbrev_map here..
12 (process_debug_info): ..or here. Warn on another case of not
13 finding a neeeded abbrev.
14
15Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe]
16
17Signed-off-by: Pgowda <pgowda.cve@gmail.com>
18---
19 binutils/dwarf.c | 216 +++++++++++++++++++++++------------------------
20 1 file changed, 106 insertions(+), 110 deletions(-)
21
22diff --git a/binutils/dwarf.c b/binutils/dwarf.c
23index 2b1eec49422..267ed3bb382 100644
24--- a/binutils/dwarf.c
25+++ b/binutils/dwarf.c
26@@ -806,7 +806,7 @@ fetch_indexed_value (dwarf_vma idx,
27 pointer_size = 4;
28 bias = 12;
29 }
30-
31+
32 dwarf_vma offset = idx * pointer_size;
33
34 /* Offsets are biased by the size of the section header
35@@ -908,38 +908,41 @@ record_abbrev_list_for_cu (dwarf_vma sta
36 next_free_abbrev_map_entry ++;
37 }
38
39-static void
40-free_all_abbrevs (void)
41+static abbrev_list *
42+free_abbrev_list (abbrev_list *list)
43 {
44- abbrev_list * list;
45+ abbrev_entry *abbrv = list->first_abbrev;
46
47- for (list = abbrev_lists; list != NULL;)
48+ while (abbrv)
49 {
50- abbrev_list * next = list->next;
51- abbrev_entry * abbrv;
52+ abbrev_attr *attr = abbrv->first_attr;
53
54- for (abbrv = list->first_abbrev; abbrv != NULL;)
55+ while (attr)
56 {
57- abbrev_entry * next_abbrev = abbrv->next;
58- abbrev_attr * attr;
59-
60- for (attr = abbrv->first_attr; attr;)
61- {
62- abbrev_attr *next_attr = attr->next;
63-
64- free (attr);
65- attr = next_attr;
66- }
67-
68- free (abbrv);
69- abbrv = next_abbrev;
70+ abbrev_attr *next_attr = attr->next;
71+ free (attr);
72+ attr = next_attr;
73 }
74
75- free (list);
76- list = next;
77+ abbrev_entry *next_abbrev = abbrv->next;
78+ free (abbrv);
79+ abbrv = next_abbrev;
80 }
81
82- abbrev_lists = NULL;
83+ abbrev_list *next = list->next;
84+ free (list);
85+ return next;
86+}
87+
88+static void
89+free_all_abbrevs (void)
90+{
91+ while (abbrev_lists)
92+ abbrev_lists = free_abbrev_list (abbrev_lists);
93+
94+ free (cu_abbrev_map);
95+ cu_abbrev_map = NULL;
96+ next_free_abbrev_map_entry = 0;
97 }
98
99 static abbrev_list *
100@@ -971,7 +974,7 @@ find_abbrev_map_by_offset (dwarf_vma off
101 && cu_abbrev_map[i].end > offset)
102 return cu_abbrev_map + i;
103
104- return NULL;
105+ return NULL;
106 }
107
108 static void
109@@ -1094,7 +1097,7 @@ process_abbrev_set (struct dwarf_section
110 }
111
112 /* Report the missing single zero which ends the section. */
113- error (_(".debug_abbrev section not zero terminated\n"));
114+ error (_("%s section not zero terminated\n"), section->name);
115
116 free (list);
117 return NULL;
118@@ -1875,7 +1878,7 @@ fetch_alt_indirect_string (dwarf_vma off
119 dwarf_vmatoa ("x", offset));
120 return _("<offset is too big>");
121 }
122-
123+
124 static const char *
125 get_AT_name (unsigned long attribute)
126 {
127@@ -2157,7 +2160,8 @@ get_type_abbrev_from_form (unsigned long
128 case DW_FORM_ref4:
129 case DW_FORM_ref8:
130 case DW_FORM_ref_udata:
131- if (uvalue + cu_offset > (size_t) (cu_end - section->start))
132+ if (uvalue + cu_offset < uvalue
133+ || uvalue + cu_offset > (size_t) (cu_end - section->start))
134 {
135 warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"),
136 uvalue, (long) cu_offset, (long) (cu_end - section->start));
137@@ -2194,7 +2198,7 @@ get_type_abbrev_from_form (unsigned long
138 else
139 *map_return = NULL;
140 }
141-
142+
143 READ_ULEB (abbrev_number, data, section->start + section->size);
144
145 for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next)
146@@ -2783,10 +2787,10 @@ read_and_display_attr_value (unsigned lo
147 if (form == DW_FORM_loclistx)
148 {
149 if (dwo)
150- {
151- index = fetch_indexed_value (uvalue, loclists_dwo, 0);
152- index += (offset_size == 8) ? 20 : 12;
153- }
154+ {
155+ index = fetch_indexed_value (uvalue, loclists_dwo, 0);
156+ index += (offset_size == 8) ? 20 : 12;
157+ }
158 else if (debug_info_p == NULL)
159 {
160 index = fetch_indexed_value (uvalue, loclists, 0);
161@@ -2804,21 +2808,21 @@ read_and_display_attr_value (unsigned lo
162 else if (form == DW_FORM_rnglistx)
163 {
164 if (dwo)
165- {
166- index = fetch_indexed_value (uvalue, rnglists_dwo, 0);
167- index += (offset_size == 8) ? 20 : 12;
168- }
169+ {
170+ index = fetch_indexed_value (uvalue, rnglists_dwo, 0);
171+ index += (offset_size == 8) ? 20 : 12;
172+ }
173 else
174- {
175- if (debug_info_p == NULL)
176- base = 0;
177- else
178- base = debug_info_p->rnglists_base;
179- /* We do not have a cached value this time, so we perform the
180- computation manually. */
181- index = fetch_indexed_value (uvalue, rnglists, base);
182- index += base;
183- }
184+ {
185+ if (debug_info_p == NULL)
186+ base = 0;
187+ else
188+ base = debug_info_p->rnglists_base;
189+ /* We do not have a cached value this time, so we perform the
190+ computation manually. */
191+ index = fetch_indexed_value (uvalue, rnglists, base);
192+ index += base;
193+ }
194 }
195 else
196 {
197@@ -2844,7 +2848,7 @@ read_and_display_attr_value (unsigned lo
198 if (!do_loc)
199 printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
200 break;
201-
202+
203 default:
204 warn (_("Unrecognized form: 0x%lx\n"), form);
205 /* What to do? Consume a byte maybe? */
206@@ -2869,9 +2873,9 @@ read_and_display_attr_value (unsigned lo
207 case DW_AT_rnglists_base:
208 if (debug_info_p->rnglists_base)
209 warn (_("CU @ 0x%s has multiple rnglists_base values (0x%s and 0x%s)"),
210- dwarf_vmatoa ("x", debug_info_p->cu_offset),
211- dwarf_vmatoa ("x", debug_info_p->rnglists_base),
212- dwarf_vmatoa ("x", uvalue));
213+ dwarf_vmatoa ("x", debug_info_p->cu_offset),
214+ dwarf_vmatoa ("x", debug_info_p->rnglists_base),
215+ dwarf_vmatoa ("x", uvalue));
216 debug_info_p->rnglists_base = uvalue;
217 break;
218 case DW_AT_str_offsets_base:
219@@ -3021,7 +3025,7 @@ read_and_display_attr_value (unsigned lo
220 case DW_FORM_strx3:
221 case DW_FORM_strx4:
222 add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false,
223- debug_info_p->str_offsets_base),
224+ debug_info_p->str_offsets_base),
225 cu_offset);
226 break;
227 case DW_FORM_string:
228@@ -3055,7 +3059,7 @@ read_and_display_attr_value (unsigned lo
229 case DW_FORM_strx3:
230 case DW_FORM_strx4:
231 add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false,
232- debug_info_p->str_offsets_base),
233+ debug_info_p->str_offsets_base),
234 cu_offset);
235 break;
236 case DW_FORM_string:
237@@ -3686,11 +3690,8 @@ process_debug_info (struct dwarf_section
238 introduce (section, false);
239
240 free_all_abbrevs ();
241- free (cu_abbrev_map);
242- cu_abbrev_map = NULL;
243- next_free_abbrev_map_entry = 0;
244
245- /* In order to be able to resolve DW_FORM_ref_attr forms we need
246+ /* In order to be able to resolve DW_FORM_ref_addr forms we need
247 to load *all* of the abbrevs for all CUs in this .debug_info
248 section. This does effectively mean that we (partially) read
249 every CU header twice. */
250@@ -4045,12 +4046,11 @@ process_debug_info (struct dwarf_section
251
252 /* Scan through the abbreviation list until we reach the
253 correct entry. */
254- if (list == NULL)
255- continue;
256-
257- for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
258- if (entry->number == abbrev_number)
259- break;
260+ entry = NULL;
261+ if (list != NULL)
262+ for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
263+ if (entry->number == abbrev_number)
264+ break;
265
266 if (entry == NULL)
267 {
268@@ -4074,7 +4074,7 @@ process_debug_info (struct dwarf_section
269 break;
270 case DW_TAG_compile_unit:
271 case DW_TAG_skeleton_unit:
272- need_base_address = 1;
273+ need_base_address = 1;
274 need_dwo_info = do_loc;
275 break;
276 case DW_TAG_entry_point:
277@@ -4459,7 +4459,7 @@ display_debug_sup (struct dwarf_section
278
279 SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end);
280 if (is_supplementary != 0 && is_supplementary != 1)
281- warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
282+ warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
283
284 sup_filename = start;
285 if (is_supplementary && sup_filename[0] != 0)
286@@ -5638,7 +5638,7 @@ display_debug_lines_decoded (struct dwar
287 printf ("%s %11d %#18" DWARF_VMA_FMT "x",
288 newFileName, state_machine_regs.line,
289 state_machine_regs.address);
290- }
291+ }
292 else
293 {
294 if (xop == -DW_LNE_end_sequence)
295@@ -6092,7 +6092,7 @@ display_debug_macro (struct dwarf_sectio
296 load_debug_section_with_follow (str, file);
297 load_debug_section_with_follow (line, file);
298 load_debug_section_with_follow (str_index, file);
299-
300+
301 introduce (section, false);
302
303 while (curr < end)
304@@ -6537,7 +6537,7 @@ display_loc_list (struct dwarf_section *
305
306 /* Check base address specifiers. */
307 if (is_max_address (begin, pointer_size)
308- && !is_max_address (end, pointer_size))
309+ && !is_max_address (end, pointer_size))
310 {
311 base_address = end;
312 print_dwarf_vma (begin, pointer_size);
313@@ -6715,7 +6715,7 @@ display_loclists_list (struct dwarf_sect
314 case DW_LLE_default_location:
315 begin = end = 0;
316 break;
317-
318+
319 case DW_LLE_offset_pair:
320 READ_ULEB (begin, start, section_end);
321 begin += base_address;
322@@ -7011,7 +7011,7 @@ display_offset_entry_loclists (struct dw
323 unsigned char * start = section->start;
324 unsigned char * const end = start + section->size;
325
326- introduce (section, false);
327+ introduce (section, false);
328
329 do
330 {
331@@ -7060,14 +7060,14 @@ display_offset_entry_loclists (struct dw
332 section->name, segment_selector_size);
333 return 0;
334 }
335-
336+
337 if (offset_entry_count == 0)
338 {
339 warn (_("The %s section contains a table without offset\n"),
340 section->name);
341 return 0;
342 }
343-
344+
345 printf (_("\n Offset Entries starting at 0x%lx:\n"),
346 (long)(start - section->start));
347
348@@ -8229,7 +8229,7 @@ display_debug_rnglists (struct dwarf_sec
349 start = display_debug_rnglists_list
350 (start, end, address_size, offset, 0, offset_size);
351 if (start >= end)
352- break;
353+ break;
354 }
355
356 start = end;
357@@ -8347,12 +8347,12 @@ display_debug_ranges (struct dwarf_secti
358 next = section_begin + offset + debug_info_p->rnglists_base;
359
360 /* If multiple DWARF entities reference the same range then we will
361- have multiple entries in the `range_entries' list for the same
362- offset. Thanks to the sort above these will all be consecutive in
363- the `range_entries' list, so we can easily ignore duplicates
364- here. */
365+ have multiple entries in the `range_entries' list for the same
366+ offset. Thanks to the sort above these will all be consecutive in
367+ the `range_entries' list, so we can easily ignore duplicates
368+ here. */
369 if (i > 0 && last_offset == offset)
370- continue;
371+ continue;
372 last_offset = offset;
373
374 if (dwarf_check != 0 && i > 0)
375@@ -10286,7 +10286,7 @@ display_debug_names (struct dwarf_sectio
376 printf (_("Out of %lu items there are %zu bucket clashes"
377 " (longest of %zu entries).\n"),
378 (unsigned long) name_count, hash_clash_count, longest_clash);
379-
380+
381 if (name_count != buckets_filled + hash_clash_count)
382 warn (_("The name_count (%lu) is not the same as the used bucket_count (%lu) + the hash clash count (%lu)"),
383 (unsigned long) name_count,
384@@ -10390,7 +10390,7 @@ display_debug_names (struct dwarf_sectio
385 break;
386 if (tagno >= 0)
387 printf ("%s<%lu>",
388- (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
389+ (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
390 (unsigned long) abbrev_tag);
391
392 for (entry = abbrev_lookup;
393@@ -10919,7 +10919,7 @@ process_cu_tu_index (struct dwarf_sectio
394 Check for integer overflow (can occur when size_t is 32-bit)
395 with overlarge ncols or nused values. */
396 if (nused == -1u
397- || _mul_overflow ((size_t) ncols, 4, &temp)
398+ || _mul_overflow ((size_t) ncols, 4, &temp)
399 || _mul_overflow ((size_t) nused + 1, temp, &total)
400 || total > (size_t) (limit - ppool))
401 {
402@@ -10927,7 +10927,7 @@ process_cu_tu_index (struct dwarf_sectio
403 section->name);
404 return 0;
405 }
406-
407+
408 if (do_display)
409 {
410 printf (_(" Offset table\n"));
411@@ -11431,8 +11431,8 @@ add_separate_debug_file (const char * fi
412
413 static bool
414 debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
415- char ** filename,
416- void * file)
417+ char ** filename,
418+ void * file)
419 {
420 size_t build_id_len;
421 unsigned char * build_id;
422@@ -11450,14 +11450,14 @@ debuginfod_fetch_separate_debug_info (st
423
424 filelen = strnlen ((const char *)section->start, section->size);
425 if (filelen == section->size)
426- /* Corrupt debugaltlink. */
427- return false;
428+ /* Corrupt debugaltlink. */
429+ return false;
430
431 build_id = section->start + filelen + 1;
432 build_id_len = section->size - (filelen + 1);
433
434 if (build_id_len == 0)
435- return false;
436+ return false;
437 }
438 else
439 return false;
440@@ -11469,25 +11469,25 @@ debuginfod_fetch_separate_debug_info (st
441
442 client = debuginfod_begin ();
443 if (client == NULL)
444- return false;
445+ return false;
446
447 /* Query debuginfod servers for the target file. If found its path
448- will be stored in filename. */
449+ will be stored in filename. */
450 fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename);
451 debuginfod_end (client);
452
453 /* Only free build_id if we allocated space for a hex string
454- in get_build_id (). */
455+ in get_build_id (). */
456 if (build_id_len == 0)
457- free (build_id);
458+ free (build_id);
459
460 if (fd >= 0)
461- {
462- /* File successfully retrieved. Close fd since we want to
463- use open_debug_file () on filename instead. */
464- close (fd);
465- return true;
466- }
467+ {
468+ /* File successfully retrieved. Close fd since we want to
469+ use open_debug_file () on filename instead. */
470+ close (fd);
471+ return true;
472+ }
473 }
474
475 return false;
476@@ -11500,7 +11500,7 @@ load_separate_debug_info (const char *
477 parse_func_type parse_func,
478 check_func_type check_func,
479 void * func_data,
480- void * file ATTRIBUTE_UNUSED)
481+ void * file ATTRIBUTE_UNUSED)
482 {
483 const char * separate_filename;
484 char * debug_filename;
485@@ -11616,11 +11616,11 @@ load_separate_debug_info (const char *
486 & tmp_filename,
487 file))
488 {
489- /* File successfully downloaded from server, replace
490- debug_filename with the file's path. */
491- free (debug_filename);
492- debug_filename = tmp_filename;
493- goto found;
494+ /* File successfully downloaded from server, replace
495+ debug_filename with the file's path. */
496+ free (debug_filename);
497+ debug_filename = tmp_filename;
498+ goto found;
499 }
500 }
501 #endif
502@@ -11787,12 +11787,12 @@ load_build_id_debug_file (const char * m
503 /* In theory we should extract the contents of the section into
504 a note structure and then check the fields. For now though
505 just use hard coded offsets instead:
506-
507+
508 Field Bytes Contents
509 NSize 0...3 4
510 DSize 4...7 8+
511 Type 8..11 3 (NT_GNU_BUILD_ID)
512- Name 12.15 GNU\0
513+ Name 12.15 GNU\0
514 Data 16.... */
515
516 /* FIXME: Check the name size, name and type fields. */
517@@ -11804,7 +11804,7 @@ load_build_id_debug_file (const char * m
518 warn (_(".note.gnu.build-id data size is too small\n"));
519 return;
520 }
521-
522+
523 if (build_id_size > (section->size - 16))
524 {
525 warn (_(".note.gnu.build-id data size is too bug\n"));
526@@ -12100,10 +12100,6 @@ free_debug_memory (void)
527
528 free_all_abbrevs ();
529
530- free (cu_abbrev_map);
531- cu_abbrev_map = NULL;
532- next_free_abbrev_map_entry = 0;
533-
534 free (shndx_pool);
535 shndx_pool = NULL;
536 shndx_pool_size = 0;
diff --git a/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch
new file mode 100644
index 0000000000..04d06ed6b6
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0014-CVE-2022-38128-3.patch
@@ -0,0 +1,95 @@
1From 695c6dfe7e85006b98c8b746f3fd5f913c94ebff Mon Sep 17 00:00:00 2001
2From: Alan Modra <amodra@gmail.com>
3Date: Thu, 21 Jul 2022 09:56:15 +0930
4Subject: [PATCH] PR29370, infinite loop in display_debug_abbrev
5
6The PR29370 testcase is a fuzzed object file with multiple
7.trace_abbrev sections. Multiple .trace_abbrev or .debug_abbrev
8sections are not a violation of the DWARF standard. The DWARF5
9standard even gives an example of multiple .debug_abbrev sections
10contained in groups. Caching and lookup of processed abbrevs thus
11needs to be done by section and offset rather than base and offset.
12(Why base anyway?) Or, since section contents are kept, by a pointer
13into the contents.
14
15 PR 29370
16 * dwarf.c (struct abbrev_list): Replace abbrev_base and
17 abbrev_offset with raw field.
18 (find_abbrev_list_by_abbrev_offset): Delete.
19 (find_abbrev_list_by_raw_abbrev): New function.
20 (process_abbrev_set): Set list->raw and list->next.
21 (find_and_process_abbrev_set): Replace abbrev list lookup with
22 new function. Don't set list abbrev_base, abbrev_offset or next.
23
24Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=695c6dfe7e85006b98c8b746f3fd5f913c94ebff]
25
26Signed-off-by: Pgowda <pgowda.cve@gmail.com>
27---
28 binutils/dwarf.c | 19 ++++++-------------
29 1 file changed, 6 insertions(+), 13 deletions(-)
30
31diff --git a/binutils/dwarf.c b/binutils/dwarf.c
32index 2fc352f74c5..99fb3566994 100644
33--- a/binutils/dwarf.c
34+++ b/binutils/dwarf.c
35@@ -856,8 +856,7 @@ typedef struct abbrev_list
36 {
37 abbrev_entry * first_abbrev;
38 abbrev_entry * last_abbrev;
39- dwarf_vma abbrev_base;
40- dwarf_vma abbrev_offset;
41+ unsigned char * raw;
42 struct abbrev_list * next;
43 unsigned char * start_of_next_abbrevs;
44 }
45@@ -946,14 +945,12 @@ free_all_abbrevs (void)
46 }
47
48 static abbrev_list *
49-find_abbrev_list_by_abbrev_offset (dwarf_vma abbrev_base,
50- dwarf_vma abbrev_offset)
51+find_abbrev_list_by_raw_abbrev (unsigned char *raw)
52 {
53 abbrev_list * list;
54
55 for (list = abbrev_lists; list != NULL; list = list->next)
56- if (list->abbrev_base == abbrev_base
57- && list->abbrev_offset == abbrev_offset)
58+ if (list->raw == raw)
59 return list;
60
61 return NULL;
62@@ -1040,6 +1037,7 @@ process_abbrev_set (struct dwarf_section
63 abbrev_list *list = xmalloc (sizeof (*list));
64 list->first_abbrev = NULL;
65 list->last_abbrev = NULL;
66+ list->raw = start;
67
68 while (start < end)
69 {
70@@ -1055,6 +1053,7 @@ process_abbrev_set (struct dwarf_section
71 the caller. */
72 if (start == end || entry == 0)
73 {
74+ list->next = NULL;
75 list->start_of_next_abbrevs = start != end ? start : NULL;
76 return list;
77 }
78@@ -1144,16 +1143,10 @@ find_and_process_abbrev_set (struct dwar
79 unsigned char *end = section->start + abbrev_base + abbrev_size;
80 abbrev_list *list = NULL;
81 if (free_list)
82- list = find_abbrev_list_by_abbrev_offset (abbrev_base, abbrev_offset);
83+ list = find_abbrev_list_by_raw_abbrev (start);
84 if (list == NULL)
85 {
86 list = process_abbrev_set (section, start, end);
87- if (list)
88- {
89- list->abbrev_base = abbrev_base;
90- list->abbrev_offset = abbrev_offset;
91- list->next = NULL;
92- }
93 if (free_list)
94 *free_list = list;
95 }