_bfd_elf_slurp_secondary_reloc_section sanity check
authorAlan Modra <amodra@gmail.com>
Wed, 7 Dec 2022 03:19:49 +0000 (13:49 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 7 Dec 2022 03:51:09 +0000 (14:21 +1030)
* elf.c (_bfd_elf_slurp_secondary_reloc_section): Sanity check
section header against file size.  Avoid overflow in
reloc_count.

bfd/elf.c

index ac10715fa93bf52c4659ca49f3a5c42c4abc7398..5548efc44e478a663e6327743f0491ff13904c9a 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -13154,6 +13154,7 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
   asection * relsec;
   bool result = true;
   bfd_vma (*r_sym) (bfd_vma);
+  ufile_ptr filesize;
 
 #if BFD_DEFAULT_TARGET_SIZE > 32
   if (bfd_arch_bits_per_address (abfd) != 32)
@@ -13167,6 +13168,7 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
 
   /* Discover if there are any secondary reloc sections
      associated with SEC.  */
+  filesize = bfd_get_file_size (abfd);
   for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
     {
       Elf_Internal_Shdr * hdr = & elf_section_data (relsec)->this_hdr;
@@ -13180,10 +13182,10 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
          bfd_byte * native_reloc;
          arelent * internal_relocs;
          arelent * internal_reloc;
-         unsigned int i;
+         size_t i;
          unsigned int entsize;
          unsigned int symcount;
-         unsigned int reloc_count;
+         bfd_size_type reloc_count;
          size_t amt;
 
          if (ebd->elf_info_to_howto == NULL)
@@ -13195,6 +13197,15 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
 #endif
          entsize = hdr->sh_entsize;
 
+         if (filesize != 0
+             && ((ufile_ptr) hdr->sh_offset > filesize
+                 || hdr->sh_size > filesize - hdr->sh_offset))
+           {
+             bfd_set_error (bfd_error_file_truncated);
+             result = false;
+             continue;
+           }
+
          native_relocs = bfd_malloc (hdr->sh_size);
          if (native_relocs == NULL)
            {
@@ -13268,7 +13279,7 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
                {
                  _bfd_error_handler
                    /* xgettext:c-format */
-                   (_("%pB(%pA): relocation %d has invalid symbol index %ld"),
+                   (_("%pB(%pA): relocation %zu has invalid symbol index %lu"),
                     abfd, sec, i, (long) r_sym (rela.r_info));
                  bfd_set_error (bfd_error_bad_value);
                  internal_reloc->sym_ptr_ptr =