Prevent a memory allocation failure when parsing corrupt DWARF debug sections.
authorNick Clifton <nickc@redhat.com>
Thu, 26 Nov 2020 17:08:33 +0000 (17:08 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 26 Nov 2020 17:08:33 +0000 (17:08 +0000)
PR 26946
* dwarf2.c (read_section): Check for debug sections with excessive
sizes.

bfd/ChangeLog
bfd/dwarf2.c

index eeb0b81f2e757a57211e35af42bcba3d31366bbb..cbc3464b9d45c38ad5ef1cf27765638df63686e0 100644 (file)
@@ -1,3 +1,9 @@
+2020-11-26  Nick Clifton  <nickc@redhat.com>
+
+       PR 26946
+       * dwarf2.c (read_section): Check for debug sections with excessive
+       sizes.
+
 2020-11-25  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR ld/26936
index 977bf43a6a181d97fa3ae71329478f9f263b090f..8bbfc81d3e7df67bf41a54092a04ca7a4d2569ed 100644 (file)
@@ -531,22 +531,24 @@ read_section (bfd *             abfd,
              bfd_byte **     section_buffer,
              bfd_size_type * section_size)
 {
-  asection *msec;
   const char *section_name = sec->uncompressed_name;
   bfd_byte *contents = *section_buffer;
-  bfd_size_type amt;
 
   /* The section may have already been read.  */
   if (contents == NULL)
     {
+      bfd_size_type amt;
+      asection *msec;
+      ufile_ptr filesize;
+
       msec = bfd_get_section_by_name (abfd, section_name);
-      if (! msec)
+      if (msec == NULL)
        {
          section_name = sec->compressed_name;
          if (section_name != NULL)
            msec = bfd_get_section_by_name (abfd, section_name);
        }
-      if (! msec)
+      if (msec == NULL)
        {
          _bfd_error_handler (_("DWARF error: can't find %s section."),
                              sec->uncompressed_name);
@@ -554,12 +556,23 @@ read_section (bfd *             abfd,
          return FALSE;
        }
 
-      *section_size = msec->rawsize ? msec->rawsize : msec->size;
+      amt = bfd_get_section_limit_octets (abfd, msec);
+      filesize = bfd_get_file_size (abfd);
+      if (amt >= filesize)
+       {
+         /* PR 26946 */
+         _bfd_error_handler (_("DWARF error: section %s is larger than its filesize! (0x%lx vs 0x%lx)"),
+                             section_name, (long) amt, (long) filesize);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      *section_size = amt;
       /* Paranoia - alloc one extra so that we can make sure a string
         section is NUL terminated.  */
-      amt = *section_size + 1;
+      amt += 1;
       if (amt == 0)
        {
+         /* Paranoia - this should never happen.  */
          bfd_set_error (bfd_error_no_memory);
          return FALSE;
        }