summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch')
-rw-r--r--meta/recipes-devtools/binutils/binutils/0018-CVE-2022-38128-2.patch436
1 files changed, 436 insertions, 0 deletions
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 @@
+From 175b91507b83ad42607d2f6dadaf55b7b511bdbe Mon Sep 17 00:00:00 2001
+From: Alan Modra <amodra@gmail.com>
+Date: Wed, 20 Jul 2022 18:28:50 +0930
+Subject: [PATCH] miscellaneous dwarf.c tidies
+
+ * dwarf.c: Leading and trailing whitespace fixes.
+ (free_abbrev_list): New function.
+ (free_all_abbrevs): Use the above. Free cu_abbrev_map here too.
+ (process_abbrev_set): Print actual section name on error.
+ (get_type_abbrev_from_form): Add overflow check.
+ (free_debug_memory): Don't free cu_abbrev_map here..
+ (process_debug_info): ..or here. Warn on another case of not
+ finding a neeeded abbrev.
+
+Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=175b91507b83ad42607d2f6dadaf55b7b511bdbe]
+
+Signed-off-by: Pgowda <pgowda.cve@gmail.com>
+---
+ binutils/dwarf.c | 216 +++++++++++++++++++++++------------------------
+ 1 file changed, 106 insertions(+), 110 deletions(-)
+
+diff --git a/binutils/dwarf.c b/binutils/dwarf.c
+index 2b1eec49422..267ed3bb382 100644
+--- a/binutils/dwarf.c
++++ b/binutils/dwarf.c
+@@ -954,38 +954,41 @@ record_abbrev_list_for_cu (dwarf_vma sta
+ next_free_abbrev_map_entry ++;
+ }
+
+-static void
+-free_all_abbrevs (void)
++static abbrev_list *
++free_abbrev_list (abbrev_list *list)
+ {
+- abbrev_list * list;
++ abbrev_entry *abbrv = list->first_abbrev;
+
+- for (list = abbrev_lists; list != NULL;)
++ while (abbrv)
+ {
+- abbrev_list * next = list->next;
+- abbrev_entry * abbrv;
++ abbrev_attr *attr = abbrv->first_attr;
+
+- for (abbrv = list->first_abbrev; abbrv != NULL;)
++ while (attr)
+ {
+- abbrev_entry * next_abbrev = abbrv->next;
+- abbrev_attr * attr;
+-
+- for (attr = abbrv->first_attr; attr;)
+- {
+- abbrev_attr *next_attr = attr->next;
+-
+- free (attr);
+- attr = next_attr;
+- }
+-
+- free (abbrv);
+- abbrv = next_abbrev;
++ abbrev_attr *next_attr = attr->next;
++ free (attr);
++ attr = next_attr;
+ }
+
+- free (list);
+- list = next;
++ abbrev_entry *next_abbrev = abbrv->next;
++ free (abbrv);
++ abbrv = next_abbrev;
+ }
+
+- abbrev_lists = NULL;
++ abbrev_list *next = list->next;
++ free (list);
++ return next;
++}
++
++static void
++free_all_abbrevs (void)
++{
++ while (abbrev_lists)
++ abbrev_lists = free_abbrev_list (abbrev_lists);
++
++ free (cu_abbrev_map);
++ cu_abbrev_map = NULL;
++ next_free_abbrev_map_entry = 0;
+ }
+
+ static abbrev_list *
+@@ -1017,7 +1020,7 @@ find_abbrev_map_by_offset (dwarf_vma off
+ && cu_abbrev_map[i].end > offset)
+ return cu_abbrev_map + i;
+
+- return NULL;
++ return NULL;
+ }
+
+ static void
+@@ -1140,7 +1143,7 @@ process_abbrev_set (struct dwarf_section
+ }
+
+ /* Report the missing single zero which ends the section. */
+- error (_(".debug_abbrev section not zero terminated\n"));
++ error (_("%s section not zero terminated\n"), section->name);
+
+ free (list);
+ return NULL;
+@@ -1917,7 +1920,7 @@ fetch_alt_indirect_string (dwarf_vma off
+ dwarf_vmatoa ("x", offset));
+ return _("<offset is too big>");
+ }
+-
++
+ static const char *
+ get_AT_name (unsigned long attribute)
+ {
+@@ -2199,7 +2202,8 @@ get_type_abbrev_from_form (unsigned long
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+- if (uvalue + cu_offset > (size_t) (cu_end - section->start))
++ if (uvalue + cu_offset < uvalue
++ || uvalue + cu_offset > (size_t) (cu_end - section->start))
+ {
+ warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"),
+ uvalue, (long) cu_offset, (long) (cu_end - section->start));
+@@ -2236,7 +2240,7 @@ get_type_abbrev_from_form (unsigned long
+ else
+ *map_return = NULL;
+ }
+-
++
+ READ_ULEB (abbrev_number, data, section->start + section->size);
+
+ for (entry = map->list->first_abbrev; entry != NULL; entry = entry->next)
+@@ -2837,7 +2841,7 @@ read_and_display_attr_value (unsigned lo
+ if (!do_loc)
+ printf ("%c<0x%s>", delimiter, dwarf_vmatoa ("x", uvalue + cu_offset));
+ break;
+-
++
+ default:
+ warn (_("Unrecognized form: 0x%lx\n"), form);
+ /* What to do? Consume a byte maybe? */
+@@ -3009,7 +3013,7 @@ read_and_display_attr_value (unsigned lo
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
+ add_dwo_name (fetch_indexed_string (uvalue, this_set, offset_size, false,
+- debug_info_p->str_offsets_base),
++ debug_info_p->str_offsets_base),
+ cu_offset);
+ break;
+ case DW_FORM_string:
+@@ -3043,7 +3047,7 @@ read_and_display_attr_value (unsigned lo
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
+ add_dwo_dir (fetch_indexed_string (uvalue, this_set, offset_size, false,
+- debug_info_p->str_offsets_base),
++ debug_info_p->str_offsets_base),
+ cu_offset);
+ break;
+ case DW_FORM_string:
+@@ -3671,11 +3675,8 @@ process_debug_info (struct dwarf_section
+ introduce (section, false);
+
+ free_all_abbrevs ();
+- free (cu_abbrev_map);
+- cu_abbrev_map = NULL;
+- next_free_abbrev_map_entry = 0;
+
+- /* In order to be able to resolve DW_FORM_ref_attr forms we need
++ /* In order to be able to resolve DW_FORM_ref_addr forms we need
+ to load *all* of the abbrevs for all CUs in this .debug_info
+ section. This does effectively mean that we (partially) read
+ every CU header twice. */
+@@ -4029,12 +4030,11 @@ process_debug_info (struct dwarf_section
+
+ /* Scan through the abbreviation list until we reach the
+ correct entry. */
+- if (list == NULL)
+- continue;
+-
+- for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
+- if (entry->number == abbrev_number)
+- break;
++ entry = NULL;
++ if (list != NULL)
++ for (entry = list->first_abbrev; entry != NULL; entry = entry->next)
++ if (entry->number == abbrev_number)
++ break;
+
+ if (entry == NULL)
+ {
+@@ -4442,7 +4442,7 @@ display_debug_sup (struct dwarf_section
+
+ SAFE_BYTE_GET_AND_INC (is_supplementary, start, 1, end);
+ if (is_supplementary != 0 && is_supplementary != 1)
+- warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
++ warn (_("corrupt .debug_sup section: is_supplementary not 0 or 1\n"));
+
+ sup_filename = start;
+ if (is_supplementary && sup_filename[0] != 0)
+@@ -5621,7 +5621,7 @@ display_debug_lines_decoded (struct dwar
+ printf ("%s %11d %#18" DWARF_VMA_FMT "x",
+ newFileName, state_machine_regs.line,
+ state_machine_regs.address);
+- }
++ }
+ else
+ {
+ if (xop == -DW_LNE_end_sequence)
+@@ -6075,7 +6075,7 @@ display_debug_macro (struct dwarf_sectio
+ load_debug_section_with_follow (str, file);
+ load_debug_section_with_follow (line, file);
+ load_debug_section_with_follow (str_index, file);
+-
++
+ introduce (section, false);
+
+ while (curr < end)
+@@ -6519,7 +6519,7 @@ display_loc_list (struct dwarf_section *
+
+ /* Check base address specifiers. */
+ if (is_max_address (begin, pointer_size)
+- && !is_max_address (end, pointer_size))
++ && !is_max_address (end, pointer_size))
+ {
+ base_address = end;
+ print_dwarf_vma (begin, pointer_size);
+@@ -6697,7 +6697,7 @@ display_loclists_list (struct dwarf_sect
+ case DW_LLE_default_location:
+ begin = end = 0;
+ break;
+-
++
+ case DW_LLE_offset_pair:
+ READ_ULEB (begin, start, section_end);
+ begin += base_address;
+@@ -6993,7 +6993,7 @@ display_offset_entry_loclists (struct dw
+ unsigned char * start = section->start;
+ unsigned char * const end = start + section->size;
+
+- introduce (section, false);
++ introduce (section, false);
+
+ do
+ {
+@@ -7042,14 +7042,14 @@ display_offset_entry_loclists (struct dw
+ section->name, segment_selector_size);
+ return 0;
+ }
+-
++
+ if (offset_entry_count == 0)
+ {
+ warn (_("The %s section contains a table without offset\n"),
+ section->name);
+ return 0;
+ }
+-
++
+ printf (_("\n Offset Entries starting at 0x%lx:\n"),
+ (long)(start - section->start));
+
+@@ -8295,12 +8295,12 @@ display_debug_ranges (struct dwarf_secti
+ next = section_begin + offset + debug_info_p->rnglists_base;
+
+ /* If multiple DWARF entities reference the same range then we will
+- have multiple entries in the `range_entries' list for the same
+- offset. Thanks to the sort above these will all be consecutive in
+- the `range_entries' list, so we can easily ignore duplicates
+- here. */
++ have multiple entries in the `range_entries' list for the same
++ offset. Thanks to the sort above these will all be consecutive in
++ the `range_entries' list, so we can easily ignore duplicates
++ here. */
+ if (i > 0 && last_offset == offset)
+- continue;
++ continue;
+ last_offset = offset;
+
+ if (dwarf_check != 0 && i > 0)
+@@ -10336,7 +10336,7 @@ display_debug_names (struct dwarf_sectio
+ break;
+ if (tagno >= 0)
+ printf ("%s<%lu>",
+- (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
++ (tagno == 0 && second_abbrev_tag == 0 ? " " : "\n\t"),
+ (unsigned long) abbrev_tag);
+
+ for (entry = abbrev_lookup;
+@@ -10901,7 +10901,7 @@ process_cu_tu_index (struct dwarf_sectio
+ Check for integer overflow (can occur when size_t is 32-bit)
+ with overlarge ncols or nused values. */
+ if (nused == -1u
+- || _mul_overflow ((size_t) ncols, 4, &temp)
++ || _mul_overflow ((size_t) ncols, 4, &temp)
+ || _mul_overflow ((size_t) nused + 1, temp, &total)
+ || total > (size_t) (limit - ppool))
+ {
+@@ -10909,7 +10909,7 @@ process_cu_tu_index (struct dwarf_sectio
+ section->name);
+ return 0;
+ }
+-
++
+ if (do_display)
+ {
+ printf (_(" Offset table\n"));
+@@ -11413,8 +11413,8 @@ add_separate_debug_file (const char * fi
+
+ static bool
+ debuginfod_fetch_separate_debug_info (struct dwarf_section * section,
+- char ** filename,
+- void * file)
++ char ** filename,
++ void * file)
+ {
+ size_t build_id_len;
+ unsigned char * build_id;
+@@ -11432,14 +11432,14 @@ debuginfod_fetch_separate_debug_info (st
+
+ filelen = strnlen ((const char *)section->start, section->size);
+ if (filelen == section->size)
+- /* Corrupt debugaltlink. */
+- return false;
++ /* Corrupt debugaltlink. */
++ return false;
+
+ build_id = section->start + filelen + 1;
+ build_id_len = section->size - (filelen + 1);
+
+ if (build_id_len == 0)
+- return false;
++ return false;
+ }
+ else
+ return false;
+@@ -11451,25 +11451,25 @@ debuginfod_fetch_separate_debug_info (st
+
+ client = debuginfod_begin ();
+ if (client == NULL)
+- return false;
++ return false;
+
+ /* Query debuginfod servers for the target file. If found its path
+- will be stored in filename. */
++ will be stored in filename. */
+ fd = debuginfod_find_debuginfo (client, build_id, build_id_len, filename);
+ debuginfod_end (client);
+
+ /* Only free build_id if we allocated space for a hex string
+- in get_build_id (). */
++ in get_build_id (). */
+ if (build_id_len == 0)
+- free (build_id);
++ free (build_id);
+
+ if (fd >= 0)
+- {
+- /* File successfully retrieved. Close fd since we want to
+- use open_debug_file () on filename instead. */
+- close (fd);
+- return true;
+- }
++ {
++ /* File successfully retrieved. Close fd since we want to
++ use open_debug_file () on filename instead. */
++ close (fd);
++ return true;
++ }
+ }
+
+ return false;
+@@ -11482,7 +11482,7 @@ load_separate_debug_info (const char *
+ parse_func_type parse_func,
+ check_func_type check_func,
+ void * func_data,
+- void * file ATTRIBUTE_UNUSED)
++ void * file ATTRIBUTE_UNUSED)
+ {
+ const char * separate_filename;
+ char * debug_filename;
+@@ -11597,11 +11597,11 @@ load_separate_debug_info (const char *
+ & tmp_filename,
+ file))
+ {
+- /* File successfully downloaded from server, replace
+- debug_filename with the file's path. */
+- free (debug_filename);
+- debug_filename = tmp_filename;
+- goto found;
++ /* File successfully downloaded from server, replace
++ debug_filename with the file's path. */
++ free (debug_filename);
++ debug_filename = tmp_filename;
++ goto found;
+ }
+ }
+ #endif
+@@ -11766,12 +11766,12 @@ load_build_id_debug_file (const char * m
+ /* In theory we should extract the contents of the section into
+ a note structure and then check the fields. For now though
+ just use hard coded offsets instead:
+-
++
+ Field Bytes Contents
+ NSize 0...3 4
+ DSize 4...7 8+
+ Type 8..11 3 (NT_GNU_BUILD_ID)
+- Name 12.15 GNU\0
++ Name 12.15 GNU\0
+ Data 16.... */
+
+ /* FIXME: Check the name size, name and type fields. */
+@@ -11783,7 +11783,7 @@ load_build_id_debug_file (const char * m
+ warn (_(".note.gnu.build-id data size is too small\n"));
+ return;
+ }
+-
++
+ if (build_id_size > (section->size - 16))
+ {
+ warn (_(".note.gnu.build-id data size is too bug\n"));
+@@ -12075,10 +12075,6 @@ free_debug_memory (void)
+
+ free_all_abbrevs ();
+
+- free (cu_abbrev_map);
+- cu_abbrev_map = NULL;
+- next_free_abbrev_map_entry = 0;
+-
+ free (shndx_pool);
+ shndx_pool = NULL;
+ shndx_pool_size = 0;