Memory leaks and ineffective bounds checking in wasm_scan
[deliverable/binutils-gdb.git] / bfd / bfd.c
index e92213b543eb5daaec392fd93cf0a17accbf684a..b1050626b68194e60c55b6780bb1244873e94083 100644 (file)
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,5 +1,5 @@
 /* Generic BFD library interface and support routines.
-   Copyright (C) 1990-2019 Free Software Foundation, Inc.
+   Copyright (C) 1990-2020 Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -492,7 +492,8 @@ CODE_FRAGMENT
 .static inline bfd_size_type
 .bfd_get_section_limit (const bfd *abfd, const asection *sec)
 .{
-.  return bfd_get_section_limit_octets (abfd, sec) / bfd_octets_per_byte (abfd);
+.  return (bfd_get_section_limit_octets (abfd, sec)
+.         / bfd_octets_per_byte (abfd, sec));
 .}
 .
 .{* Functions to handle insertion and deletion of a bfd's sections.  These
@@ -2539,59 +2540,57 @@ void
 bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
                               asection *sec)
 {
-  if ((abfd->flags & BFD_COMPRESS) != 0)
+  if ((abfd->flags & BFD_COMPRESS) == 0)
+    abort ();
+
+  switch (bfd_get_flavour (abfd))
     {
-      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+    case bfd_target_elf_flavour:
+      if ((abfd->flags & BFD_COMPRESS_GABI) != 0)
        {
-         if ((abfd->flags & BFD_COMPRESS_GABI) != 0)
-           {
-             const struct elf_backend_data *bed
-               = get_elf_backend_data (abfd);
+         const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
-             /* Set the SHF_COMPRESSED bit.  */
-             elf_section_flags (sec) |= SHF_COMPRESSED;
+         /* Set the SHF_COMPRESSED bit.  */
+         elf_section_flags (sec) |= SHF_COMPRESSED;
 
-             if (bed->s->elfclass == ELFCLASS32)
-               {
-                 Elf32_External_Chdr *echdr
-                   = (Elf32_External_Chdr *) contents;
-                 bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
-                 bfd_put_32 (abfd, sec->size, &echdr->ch_size);
-                 bfd_put_32 (abfd, 1 << sec->alignment_power,
-                             &echdr->ch_addralign);
-                 /* bfd_log2 (alignof (Elf32_Chdr)) */
-                 bfd_set_section_alignment (sec, 2);
-               }
-             else
-               {
-                 Elf64_External_Chdr *echdr
-                   = (Elf64_External_Chdr *) contents;
-                 bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
-                 bfd_put_32 (abfd, 0, &echdr->ch_reserved);
-                 bfd_put_64 (abfd, sec->size, &echdr->ch_size);
-                 bfd_put_64 (abfd, 1 << sec->alignment_power,
-                             &echdr->ch_addralign);
-                 /* bfd_log2 (alignof (Elf64_Chdr)) */
-                 bfd_set_section_alignment (sec, 3);
-               }
+         if (bed->s->elfclass == ELFCLASS32)
+           {
+             Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
+             bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
+             bfd_put_32 (abfd, sec->size, &echdr->ch_size);
+             bfd_put_32 (abfd, 1 << sec->alignment_power,
+                         &echdr->ch_addralign);
+             /* bfd_log2 (alignof (Elf32_Chdr)) */
+             bfd_set_section_alignment (sec, 2);
            }
          else
            {
-             /* Clear the SHF_COMPRESSED bit.  */
-             elf_section_flags (sec) &= ~SHF_COMPRESSED;
-
-             /* Write the zlib header.  It should be "ZLIB" followed by
-                the uncompressed section size, 8 bytes in big-endian
-                order.  */
-             memcpy (contents, "ZLIB", 4);
-             bfd_putb64 (sec->size, contents + 4);
-             /* No way to keep the original alignment, just use 1 always. */
-             bfd_set_section_alignment (sec, 0);
+             Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
+             bfd_put_32 (abfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
+             bfd_put_32 (abfd, 0, &echdr->ch_reserved);
+             bfd_put_64 (abfd, sec->size, &echdr->ch_size);
+             bfd_put_64 (abfd, 1 << sec->alignment_power,
+                         &echdr->ch_addralign);
+             /* bfd_log2 (alignof (Elf64_Chdr)) */
+             bfd_set_section_alignment (sec, 3);
            }
+         break;
        }
+
+      /* Clear the SHF_COMPRESSED bit.  */
+      elf_section_flags (sec) &= ~SHF_COMPRESSED;
+      /* Fall through.  */
+
+    default:
+      /* Write the zlib header.  It should be "ZLIB" followed by
+        the uncompressed section size, 8 bytes in big-endian
+        order.  */
+      memcpy (contents, "ZLIB", 4);
+      bfd_putb64 (sec->size, contents + 4);
+      /* No way to keep the original alignment, just use 1 always. */
+      bfd_set_section_alignment (sec, 0);
+      break;
     }
-  else
-    abort ();
 }
 
 /*
@@ -2769,7 +2768,7 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
 
-  /* Do nothing if ELF classes of input and output are the same. */
+  /* Do nothing if ELF classes of input and output are the same.  */
   if (get_elf_backend_data (ibfd)->s->elfclass
       == get_elf_backend_data (obfd)->s->elfclass)
     return TRUE;
@@ -2783,11 +2782,17 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
   if ((ibfd->flags & BFD_DECOMPRESS))
     return TRUE;
 
-  /* Do nothing if the input section isn't a SHF_COMPRESSED section. */
+  /* Do nothing if the input section isn't a SHF_COMPRESSED section.  */
   ihdr_size = bfd_get_compression_header_size (ibfd, isec);
   if (ihdr_size == 0)
     return TRUE;
 
+  /* PR 25221.  Check for corrupt input sections.  */
+  if (ihdr_size > bfd_get_section_limit (ibfd, isec))
+    /* FIXME: Issue a warning about a corrupt
+       compression header size field ?  */
+    return FALSE;
+
   contents = *ptr;
 
   /* Convert the contents of the input SHF_COMPRESSED section to
@@ -2804,6 +2809,12 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
 
       use_memmove = FALSE;
     }
+  else if (ihdr_size != sizeof (Elf64_External_Chdr))
+    {
+      /* FIXME: Issue a warning about a corrupt
+        compression header size field ?  */
+      return FALSE;
+    }
   else
     {
       Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
This page took 0.02626 seconds and 4 git commands to generate.