bfd: Always check sections with the corrupt size
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 4 Nov 2021 13:27:16 +0000 (06:27 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 4 Nov 2021 13:57:32 +0000 (06:57 -0700)
Always check sections with the corrupt size for non-MMO files.  Skip MMO
files for compress_status == COMPRESS_SECTION_NONE since MMO has special
handling for COMPRESS_SECTION_NONE.

PR binutils/28530
* compress.c (bfd_get_full_section_contents): Always check
sections with the corrupt size.

bfd/compress.c

index 4a2ada3e3eb42b35c2367b8743d7406f8da66cd2..a3adb8d82500c4e9676d58020413eb76d3e9793e 100644 (file)
@@ -232,6 +232,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
   bfd_size_type save_rawsize;
   bfd_byte *compressed_buffer;
   unsigned int compression_header_size;
+  ufile_ptr filesize;
 
   if (abfd->direction != write_direction && sec->rawsize != 0)
     sz = sec->rawsize;
@@ -243,34 +244,37 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
       return true;
     }
 
+  filesize = bfd_get_file_size (abfd);
+  if (filesize > 0
+      && filesize < sz
+      /* PR 24753: Linker created sections can be larger than
+        the file size, eg if they are being used to hold stubs.  */
+      && (bfd_section_flags (sec) & SEC_LINKER_CREATED) == 0
+      /* PR 24753: Sections which have no content should also be
+        excluded as they contain no size on disk.  */
+      && (bfd_section_flags (sec) & SEC_HAS_CONTENTS) != 0
+      /* PR 28530: Check compressed sections with the corrupt size.  */
+      && (sec->compress_status != COMPRESS_SECTION_NONE
+      /* The MMO file format supports its own special compression
+        technique, but it uses COMPRESS_SECTION_NONE when loading
+        a section's contents.  */
+         || bfd_get_flavour (abfd) != bfd_target_mmo_flavour))
+    {
+      /* PR 24708: Avoid attempts to allocate a ridiculous amount
+        of memory.  */
+      bfd_set_error (bfd_error_file_truncated);
+      _bfd_error_handler
+       /* xgettext:c-format */
+       (_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"),
+        abfd, sec, (uint64_t) sz, (uint64_t) filesize);
+      return false;
+    }
+
   switch (sec->compress_status)
     {
     case COMPRESS_SECTION_NONE:
       if (p == NULL)
        {
-         ufile_ptr filesize = bfd_get_file_size (abfd);
-         if (filesize > 0
-             && filesize < sz
-             /* PR 24753: Linker created sections can be larger than
-                the file size, eg if they are being used to hold stubs.  */
-             && (bfd_section_flags (sec) & SEC_LINKER_CREATED) == 0
-             /* PR 24753: Sections which have no content should also be
-                excluded as they contain no size on disk.  */
-             && (bfd_section_flags (sec) & SEC_HAS_CONTENTS) != 0
-             /* The MMO file format supports its own special compression
-                technique, but it uses COMPRESS_SECTION_NONE when loading
-                a section's contents.  */
-             && bfd_get_flavour (abfd) != bfd_target_mmo_flavour)
-           {
-             /* PR 24708: Avoid attempts to allocate a ridiculous amount
-                of memory.  */
-             bfd_set_error (bfd_error_file_truncated);
-             _bfd_error_handler
-               /* xgettext:c-format */
-               (_("error: %pB(%pA) section size (%#" PRIx64 " bytes) is larger than file size (%#" PRIx64 " bytes)"),
-                abfd, sec, (uint64_t) sz, (uint64_t) filesize);
-             return false;
-           }
          p = (bfd_byte *) bfd_malloc (sz);
          if (p == NULL)
            {