PR28047, readelf crash due to assertion failure
authorAlan Modra <amodra@gmail.com>
Sat, 3 Jul 2021 00:08:40 +0000 (09:38 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 5 Jul 2021 10:34:21 +0000 (20:04 +0930)
DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref1, and
DW_FORM_ref_udata are all supposed to be within the containing unit.

PR 28047
* dwarf.c (get_type_abbrev_from_form): Add cu_end parameter.
Check DW_FORM_ref1 etc. arg against cu_end rather than end of
section.  Adjust all callers.

binutils/ChangeLog
binutils/dwarf.c

index 9efa39ed768bcc00af33c792907cf5f00cba3d1b..77b7ac711e0300787f8e3db8aff5bae895205651 100644 (file)
@@ -1,3 +1,10 @@
+2021-07-05  Alan Modra  <amodra@gmail.com>
+
+       PR 28047
+       * dwarf.c (get_type_abbrev_from_form): Add cu_end parameter.
+       Check DW_FORM_ref1 etc. arg against cu_end rather than end of
+       section.  Adjust all callers.
+
 2021-07-03  Nick Clifton  <nickc@redhat.com>
 
        * configure: Regenerate.
index 1e7f4db7b7c890bea45ea6866808fcbcb204f393..ad1ee97d9bf54781a0cdc6fc18790a416b263110 100644 (file)
@@ -2066,6 +2066,7 @@ static abbrev_entry *
 get_type_abbrev_from_form (unsigned long form,
                           unsigned long uvalue,
                           dwarf_vma cu_offset,
+                          unsigned char *cu_end,
                           const struct dwarf_section *section,
                           unsigned long *abbrev_num_return,
                           unsigned char **data_return,
@@ -2106,10 +2107,10 @@ get_type_abbrev_from_form (unsigned long form,
     case DW_FORM_ref4:
     case DW_FORM_ref8:
     case DW_FORM_ref_udata:
-      if (uvalue + cu_offset > section->size)
+      if (uvalue + cu_offset > (size_t) (cu_end - section->start))
        {
-         warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > section size %lx\n"),
-               uvalue, (long) cu_offset, (long) section->size);
+         warn (_("Unable to resolve ref form: uvalue %lx + cu_offset %lx > CU size %lx\n"),
+               uvalue, (long) cu_offset, (long) (cu_end - section->start));
          return NULL;
        }
       uvalue += cu_offset;
@@ -2225,6 +2226,7 @@ get_type_signedness (abbrev_entry *entry,
            type_abbrev = get_type_abbrev_from_form (attr->form,
                                                     uvalue,
                                                     cu_offset,
+                                                    end,
                                                     section,
                                                     NULL /* abbrev num return */,
                                                     &type_data,
@@ -2963,8 +2965,10 @@ read_and_display_attr_value (unsigned long           attribute,
          unsigned char *type_data;
          abbrev_map *map;
 
-         type_abbrev = get_type_abbrev_from_form (form, uvalue, cu_offset,
-                                                  section, NULL, &type_data, &map);
+         type_abbrev = get_type_abbrev_from_form (form, uvalue,
+                                                  cu_offset, end,
+                                                  section, NULL,
+                                                  &type_data, &map);
          if (type_abbrev != NULL)
            {
              get_type_signedness (type_abbrev, section, type_data,
@@ -3297,7 +3301,7 @@ read_and_display_attr_value (unsigned long           attribute,
        unsigned long abbrev_number;
        abbrev_entry *entry;
 
-       entry = get_type_abbrev_from_form (form, uvalue, cu_offset,
+       entry = get_type_abbrev_from_form (form, uvalue, cu_offset, end,
                                           section, & abbrev_number, NULL, NULL);
        if (entry == NULL)
          {