summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpgowda <pgowda.cve@gmail.com>2022-10-13 13:17:26 +0530
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-10-20 15:36:01 +0100
commit1b2fb9a1a5516c80fef079c38e42066d70984773 (patch)
tree6758b1a0c360ebfc98a69e9070143608576ff1fc
parent6d80584e9f095537b8d3a2e37db3feb7c608dd69 (diff)
downloadpoky-1b2fb9a1a5516c80fef079c38e42066d70984773.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: 21fb0b441096ec8b5cfa1d5b645f9a3a2ace1e09) Signed-off-by: pgowda <pgowda.cve@gmail.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/binutils/binutils-2.38.inc3
-rw-r--r--meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-1.patch350
-rw-r--r--meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch436
-rw-r--r--meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-3.patch95
4 files changed, 884 insertions, 0 deletions
diff --git a/meta/recipes-devtools/binutils/binutils-2.38.inc b/meta/recipes-devtools/binutils/binutils-2.38.inc
index fc88d4a79e..8259ec3232 100644
--- a/meta/recipes-devtools/binutils/binutils-2.38.inc
+++ b/meta/recipes-devtools/binutils/binutils-2.38.inc
@@ -39,5 +39,8 @@ SRC_URI = "\
39 file://0017-CVE-2022-38127-2.patch \ 39 file://0017-CVE-2022-38127-2.patch \
40 file://0017-CVE-2022-38127-3.patch \ 40 file://0017-CVE-2022-38127-3.patch \
41 file://0017-CVE-2022-38127-4.patch \ 41 file://0017-CVE-2022-38127-4.patch \
42 file://0018-CVE-2022-38128-1.patch \
43 file://0018-CVE-2022-38128-2.patch \
44 file://0018-CVE-2022-38128-3.patch \
42" 45"
43S = "${WORKDIR}/git" 46S = "${WORKDIR}/git"
diff --git a/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-1.patch b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-1.patch
new file mode 100644
index 0000000000..0a490d86b3
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0018-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/0018-CVE-2022-38128-2.patch b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch
new file mode 100644
index 0000000000..b867b04e96
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch
@@ -0,0 +1,436 @@
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@@ -954,38 +954,41 @@ record_abbrev_list_for_cu (dwarf_vma sta
27 next_free_abbrev_map_entry ++;
28 }
29
30-static void
31-free_all_abbrevs (void)
32+static abbrev_list *
33+free_abbrev_list (abbrev_list *list)
34 {
35- abbrev_list * list;
36+ abbrev_entry *abbrv = list->first_abbrev;
37
38- for (list = abbrev_lists; list != NULL;)
39+ while (abbrv)
40 {
41- abbrev_list * next = list->next;
42- abbrev_entry * abbrv;
43+ abbrev_attr *attr = abbrv->first_attr;
44
45- for (abbrv = list->first_abbrev; abbrv != NULL;)
46+ while (attr)
47 {
48- abbrev_entry * next_abbrev = abbrv->next;
49- abbrev_attr * attr;
50-
51- for (attr = abbrv->first_attr; attr;)
52- {
53- abbrev_attr *next_attr = attr->next;
54-
55- free (attr);
56- attr = next_attr;
57- }
58-
59- free (abbrv);
60- abbrv = next_abbrev;
61+ abbrev_attr *next_attr = attr->next;
62+ free (attr);
63+ attr = next_attr;
64 }
65
66- free (list);
67- list = next;
68+ abbrev_entry *next_abbrev = abbrv->next;
69+ free (abbrv);
70+ abbrv = next_abbrev;
71 }
72
73- abbrev_lists = NULL;
74+ abbrev_list *next = list->next;
75+ free (list);
76+ return next;
77+}
78+
79+static void
80+free_all_abbrevs (void)
81+{
82+ while (abbrev_lists)
83+ abbrev_lists = free_abbrev_list (abbrev_lists);
84+
85+ free (cu_abbrev_map);
86+ cu_abbrev_map = NULL;
87+ next_free_abbrev_map_entry = 0;
88 }
89
90 static abbrev_list *
91@@ -1017,7 +1020,7 @@ find_abbrev_map_by_offset (dwarf_vma off
92 && cu_abbrev_map[i].end > offset)
93 return cu_abbrev_map + i;
94
95- return NULL;
96+ return NULL;
97 }
98
99 static void
100@@ -1140,7 +1143,7 @@ process_abbrev_set (struct dwarf_section
101 }
102
103 /* Report the missing single zero which ends the section. */
104- error (_(".debug_abbrev section not zero terminated\n"));
105+ error (_("%s section not zero terminated\n"), section->name);
106
107 free (list);
108 return NULL;
109@@ -1917,7 +1920,7 @@ fetch_alt_indirect_string (dwarf_vma off
110 dwarf_vmatoa ("x", offset));
111 return _("<offset is too big>");
112 }
113-
114+
115 static const char *
116 get_AT_name (unsigned long attribute)
117 {
118@@ -2199,7 +2202,8 @@ get_type_abbrev_from_form (unsigned long
119 case DW_FORM_ref4:
120 case DW_FORM_ref8:
121 case DW_FORM_ref_udata:
122- if (uvalue + cu_offset > (size_t) (cu_end - section->start))
123+ if (uvalue + cu_offset < uvalue
124+ || uvalue + cu_offset > (size_t) (cu_end - section->start))
125 {
126 warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"),
127 uvalue, (long) cu_offset, (long) (cu_end - section->start));
128@@ -2236,7 +2240,7 @@ get_type_abbrev_from_form (unsigned long
129 else
130 *map_return = NULL;
131 }
132-
133+
134 READ_ULEB (abbrev_number, data, section->start + section->size);
135
136 for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next)
137@@ -2837,7 +2841,7 @@ read_and_display_attr_value (unsigned lo
138 if (!do_loc)
139 printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
140 break;
141-
142+
143 default:
144 warn (_("Unrecognized form: 0x%lx\n"), form);
145 /* What to do? Consume a byte maybe? */
146@@ -3009,7 +3013,7 @@ read_and_display_attr_value (unsigned lo
147 case DW_FORM_strx3:
148 case DW_FORM_strx4:
149 add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false,
150- debug_info_p->str_offsets_base),
151+ debug_info_p->str_offsets_base),
152 cu_offset);
153 break;
154 case DW_FORM_string:
155@@ -3043,7 +3047,7 @@ read_and_display_attr_value (unsigned lo
156 case DW_FORM_strx3:
157 case DW_FORM_strx4:
158 add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false,
159- debug_info_p->str_offsets_base),
160+ debug_info_p->str_offsets_base),
161 cu_offset);
162 break;
163 case DW_FORM_string:
164@@ -3671,11 +3675,8 @@ process_debug_info (struct dwarf_section
165 introduce (section, false);
166
167 free_all_abbrevs ();
168- free (cu_abbrev_map);
169- cu_abbrev_map = NULL;
170- next_free_abbrev_map_entry = 0;
171
172- /* In order to be able to resolve DW_FORM_ref_attr forms we need
173+ /* In order to be able to resolve DW_FORM_ref_addr forms we need
174 to load *all* of the abbrevs for all CUs in this .debug_info
175 section. This does effectively mean that we (partially) read
176 every CU header twice. */
177@@ -4029,12 +4030,11 @@ process_debug_info (struct dwarf_section
178
179 /* Scan through the abbreviation list until we reach the
180 correct entry. */
181- if (list == NULL)
182- continue;
183-
184- for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
185- if (entry->number == abbrev_number)
186- break;
187+ entry = NULL;
188+ if (list != NULL)
189+ for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
190+ if (entry->number == abbrev_number)
191+ break;
192
193 if (entry == NULL)
194 {
195@@ -4442,7 +4442,7 @@ display_debug_sup (struct dwarf_section
196
197 SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end);
198 if (is_supplementary != 0 && is_supplementary != 1)
199- warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
200+ warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
201
202 sup_filename = start;
203 if (is_supplementary && sup_filename[0] != 0)
204@@ -5621,7 +5621,7 @@ display_debug_lines_decoded (struct dwar
205 printf ("%s %11d %#18" DWARF_VMA_FMT "x",
206 newFileName, state_machine_regs.line,
207 state_machine_regs.address);
208- }
209+ }
210 else
211 {
212 if (xop == -DW_LNE_end_sequence)
213@@ -6075,7 +6075,7 @@ display_debug_macro (struct dwarf_sectio
214 load_debug_section_with_follow (str, file);
215 load_debug_section_with_follow (line, file);
216 load_debug_section_with_follow (str_index, file);
217-
218+
219 introduce (section, false);
220
221 while (curr < end)
222@@ -6519,7 +6519,7 @@ display_loc_list (struct dwarf_section *
223
224 /* Check base address specifiers. */
225 if (is_max_address (begin, pointer_size)
226- && !is_max_address (end, pointer_size))
227+ && !is_max_address (end, pointer_size))
228 {
229 base_address = end;
230 print_dwarf_vma (begin, pointer_size);
231@@ -6697,7 +6697,7 @@ display_loclists_list (struct dwarf_sect
232 case DW_LLE_default_location:
233 begin = end = 0;
234 break;
235-
236+
237 case DW_LLE_offset_pair:
238 READ_ULEB (begin, start, section_end);
239 begin += base_address;
240@@ -6993,7 +6993,7 @@ display_offset_entry_loclists (struct dw
241 unsigned char * start = section->start;
242 unsigned char * const end = start + section->size;
243
244- introduce (section, false);
245+ introduce (section, false);
246
247 do
248 {
249@@ -7042,14 +7042,14 @@ display_offset_entry_loclists (struct dw
250 section->name, segment_selector_size);
251 return 0;
252 }
253-
254+
255 if (offset_entry_count == 0)
256 {
257 warn (_("The %s section contains a table without offset\n"),
258 section->name);
259 return 0;
260 }
261-
262+
263 printf (_("\n Offset Entries starting at 0x%lx:\n"),
264 (long)(start - section->start));
265
266@@ -8295,12 +8295,12 @@ display_debug_ranges (struct dwarf_secti
267 next = section_begin + offset + debug_info_p->rnglists_base;
268
269 /* If multiple DWARF entities reference the same range then we will
270- have multiple entries in the `range_entries' list for the same
271- offset. Thanks to the sort above these will all be consecutive in
272- the `range_entries' list, so we can easily ignore duplicates
273- here. */
274+ have multiple entries in the `range_entries' list for the same
275+ offset. Thanks to the sort above these will all be consecutive in
276+ the `range_entries' list, so we can easily ignore duplicates
277+ here. */
278 if (i > 0 && last_offset == offset)
279- continue;
280+ continue;
281 last_offset = offset;
282
283 if (dwarf_check != 0 && i > 0)
284@@ -10336,7 +10336,7 @@ display_debug_names (struct dwarf_sectio
285 break;
286 if (tagno >= 0)
287 printf ("%s<%lu>",
288- (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
289+ (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
290 (unsigned long) abbrev_tag);
291
292 for (entry = abbrev_lookup;
293@@ -10901,7 +10901,7 @@ process_cu_tu_index (struct dwarf_sectio
294 Check for integer overflow (can occur when size_t is 32-bit)
295 with overlarge ncols or nused values. */
296 if (nused == -1u
297- || _mul_overflow ((size_t) ncols, 4, &temp)
298+ || _mul_overflow ((size_t) ncols, 4, &temp)
299 || _mul_overflow ((size_t) nused + 1, temp, &total)
300 || total > (size_t) (limit - ppool))
301 {
302@@ -10909,7 +10909,7 @@ process_cu_tu_index (struct dwarf_sectio
303 section->name);
304 return 0;
305 }
306-
307+
308 if (do_display)
309 {
310 printf (_(" Offset table\n"));
311@@ -11413,8 +11413,8 @@ add_separate_debug_file (const char * fi
312
313 static bool
314 debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
315- char ** filename,
316- void * file)
317+ char ** filename,
318+ void * file)
319 {
320 size_t build_id_len;
321 unsigned char * build_id;
322@@ -11432,14 +11432,14 @@ debuginfod_fetch_separate_debug_info (st
323
324 filelen = strnlen ((const char *)section->start, section->size);
325 if (filelen == section->size)
326- /* Corrupt debugaltlink. */
327- return false;
328+ /* Corrupt debugaltlink. */
329+ return false;
330
331 build_id = section->start + filelen + 1;
332 build_id_len = section->size - (filelen + 1);
333
334 if (build_id_len == 0)
335- return false;
336+ return false;
337 }
338 else
339 return false;
340@@ -11451,25 +11451,25 @@ debuginfod_fetch_separate_debug_info (st
341
342 client = debuginfod_begin ();
343 if (client == NULL)
344- return false;
345+ return false;
346
347 /* Query debuginfod servers for the target file. If found its path
348- will be stored in filename. */
349+ will be stored in filename. */
350 fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename);
351 debuginfod_end (client);
352
353 /* Only free build_id if we allocated space for a hex string
354- in get_build_id (). */
355+ in get_build_id (). */
356 if (build_id_len == 0)
357- free (build_id);
358+ free (build_id);
359
360 if (fd >= 0)
361- {
362- /* File successfully retrieved. Close fd since we want to
363- use open_debug_file () on filename instead. */
364- close (fd);
365- return true;
366- }
367+ {
368+ /* File successfully retrieved. Close fd since we want to
369+ use open_debug_file () on filename instead. */
370+ close (fd);
371+ return true;
372+ }
373 }
374
375 return false;
376@@ -11482,7 +11482,7 @@ load_separate_debug_info (const char *
377 parse_func_type parse_func,
378 check_func_type check_func,
379 void * func_data,
380- void * file ATTRIBUTE_UNUSED)
381+ void * file ATTRIBUTE_UNUSED)
382 {
383 const char * separate_filename;
384 char * debug_filename;
385@@ -11597,11 +11597,11 @@ load_separate_debug_info (const char *
386 & tmp_filename,
387 file))
388 {
389- /* File successfully downloaded from server, replace
390- debug_filename with the file's path. */
391- free (debug_filename);
392- debug_filename = tmp_filename;
393- goto found;
394+ /* File successfully downloaded from server, replace
395+ debug_filename with the file's path. */
396+ free (debug_filename);
397+ debug_filename = tmp_filename;
398+ goto found;
399 }
400 }
401 #endif
402@@ -11766,12 +11766,12 @@ load_build_id_debug_file (const char * m
403 /* In theory we should extract the contents of the section into
404 a note structure and then check the fields. For now though
405 just use hard coded offsets instead:
406-
407+
408 Field Bytes Contents
409 NSize 0...3 4
410 DSize 4...7 8+
411 Type 8..11 3 (NT_GNU_BUILD_ID)
412- Name 12.15 GNU\0
413+ Name 12.15 GNU\0
414 Data 16.... */
415
416 /* FIXME: Check the name size, name and type fields. */
417@@ -11783,7 +11783,7 @@ load_build_id_debug_file (const char * m
418 warn (_(".note.gnu.build-id data size is too small\n"));
419 return;
420 }
421-
422+
423 if (build_id_size > (section->size - 16))
424 {
425 warn (_(".note.gnu.build-id data size is too bug\n"));
426@@ -12075,10 +12075,6 @@ free_debug_memory (void)
427
428 free_all_abbrevs ();
429
430- free (cu_abbrev_map);
431- cu_abbrev_map = NULL;
432- next_free_abbrev_map_entry = 0;
433-
434 free (shndx_pool);
435 shndx_pool = NULL;
436 shndx_pool_size = 0;
diff --git a/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-3.patch b/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-3.patch
new file mode 100644
index 0000000000..04d06ed6b6
--- /dev/null
+++ b/meta/recipes-devtools/binutils/binutils/0018-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 }