bfd_get_file_size calls
authorAlan Modra <amodra@gmail.com>
Wed, 19 Feb 2020 02:44:05 +0000 (13:14 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 19 Feb 2020 02:44:05 +0000 (13:14 +1030)
bfd_get_file_size can return 0, meaning the file size is unknown.

* coffgen.c (_bfd_coff_get_external_symbols): Don't call
bfd_get_file_size twice.
(_bfd_coff_read_string_table): Allow for bfd_get_file_size
zero, ie. unknown, return.
* elf-attrs.c (_bfd_elf_parse_attributes): Likewise.
* elfcode.h (elf_swap_shdr_in): Likewise.
(elf_object_p): Don't call bfd_get_file_size twice and correct
file size check.

bfd/ChangeLog
bfd/coffgen.c
bfd/elf-attrs.c
bfd/elfcode.h

index c7335ab3c3a75eed84f1603efa5fab631c115ed9..fe2ffd341a0cb496e90ea84180170265a93ae141 100644 (file)
@@ -1,3 +1,14 @@
+2020-02-19  Alan Modra  <amodra@gmail.com>
+
+       * coffgen.c (_bfd_coff_get_external_symbols): Don't call
+       bfd_get_file_size twice.
+       (_bfd_coff_read_string_table): Allow for bfd_get_file_size
+       zero, ie. unknown, return.
+       * elf-attrs.c (_bfd_elf_parse_attributes): Likewise.
+       * elfcode.h (elf_swap_shdr_in): Likewise.
+       (elf_object_p): Don't call bfd_get_file_size twice and correct
+       file size check.
+
 2020-02-19  Alan Modra  <amodra@gmail.com>
 
        * mach-o.c (bfd_mach_o_flatten_sections): Return a bfd_boolean,
index cf115d48c85e80449c3b2d25061075fc549646c8..5287130490ecd7b869da0c0c47594ddd9d38d0d8 100644 (file)
@@ -1642,19 +1642,20 @@ _bfd_coff_get_external_symbols (bfd *abfd)
   bfd_size_type symesz;
   bfd_size_type size;
   void * syms;
+  ufile_ptr filesize;
 
   if (obj_coff_external_syms (abfd) != NULL)
     return TRUE;
 
   symesz = bfd_coff_symesz (abfd);
-
   size = obj_raw_syment_count (abfd) * symesz;
   if (size == 0)
     return TRUE;
+
   /* Check for integer overflow and for unreasonable symbol counts.  */
+  filesize = bfd_get_file_size (abfd);
   if (size < obj_raw_syment_count (abfd)
-      || (bfd_get_file_size (abfd) > 0
-         && size > bfd_get_file_size (abfd)))
+      || (filesize != 0 && size > filesize))
 
     {
       _bfd_error_handler (_("%pB: corrupt symbol count: %#" PRIx64 ""),
@@ -1698,6 +1699,7 @@ _bfd_coff_read_string_table (bfd *abfd)
   bfd_size_type strsize;
   char *strings;
   file_ptr pos;
+  ufile_ptr filesize;
 
   if (obj_coff_strings (abfd) != NULL)
     return obj_coff_strings (abfd);
@@ -1731,7 +1733,9 @@ _bfd_coff_read_string_table (bfd *abfd)
 #endif
     }
 
-  if (strsize < STRING_SIZE_SIZE || strsize > bfd_get_file_size (abfd))
+  filesize = bfd_get_file_size (abfd);
+  if (strsize < STRING_SIZE_SIZE
+      || (filesize != 0 && strsize > filesize))
     {
       _bfd_error_handler
        /* xgettext: c-format */
index 169b69738101559bb34cc4e3e751628d65de0d5a..070104c27344322d286c9b8cf2bd8ab17e4693d9 100644 (file)
@@ -436,11 +436,14 @@ _bfd_elf_parse_attributes (bfd *abfd, Elf_Internal_Shdr * hdr)
   bfd_byte *p_end;
   bfd_vma len;
   const char *std_sec;
+  ufile_ptr filesize;
 
   /* PR 17512: file: 2844a11d.  */
   if (hdr->sh_size == 0)
     return;
-  if (hdr->sh_size > bfd_get_file_size (abfd))
+
+  filesize = bfd_get_file_size (abfd);
+  if (filesize != 0 && hdr->sh_size > filesize)
     {
       /* xgettext:c-format */
       _bfd_error_handler (_("%pB: error: attribute section '%pA' too big: %#llx"),
index e1e89cf78f2da34186d08670423a9211e3a8a834..a6b0c613ba24df7be8d96f8113861ef1db2598e7 100644 (file)
@@ -317,11 +317,16 @@ elf_swap_shdr_in (bfd *abfd,
   /* PR 23657.  Check for invalid section size, in sections with contents.
      Note - we do not set an error value here because the contents
      of this particular section might not be needed by the consumer.  */
-  if (dst->sh_type != SHT_NOBITS
-      && dst->sh_size > bfd_get_file_size (abfd))
-    _bfd_error_handler
-      (_("warning: %pB has a corrupt section with a size (%" BFD_VMA_FMT "x) larger than the file size"),
-       abfd, dst->sh_size);
+  if (dst->sh_type != SHT_NOBITS)
+    {
+      ufile_ptr filesize = bfd_get_file_size (abfd);
+
+      if (filesize != 0 && dst->sh_size > filesize)
+       _bfd_error_handler
+         (_("warning: %pB has a corrupt section with a size (%"
+            BFD_VMA_FMT "x) larger than the file size"),
+          abfd, dst->sh_size);
+    }
   dst->sh_link = H_GET_32 (abfd, src->sh_link);
   dst->sh_info = H_GET_32 (abfd, src->sh_info);
   dst->sh_addralign = H_GET_WORD (abfd, src->sh_addralign);
@@ -775,6 +780,7 @@ elf_object_p (bfd *abfd)
     {
       Elf_Internal_Phdr *i_phdr;
       unsigned int i;
+      ufile_ptr filesize;
 
 #ifndef BFD64
       if (i_ehdrp->e_phnum > ((bfd_size_type) -1) / sizeof (*i_phdr))
@@ -782,9 +788,10 @@ elf_object_p (bfd *abfd)
 #endif
       /* Check for a corrupt input file with an impossibly large number
         of program headers.  */
-      if (bfd_get_file_size (abfd) > 0
-         && i_ehdrp->e_phnum > bfd_get_file_size (abfd))
-       goto got_no_match;
+      filesize = bfd_get_file_size (abfd);
+      if (filesize != 0
+         && i_ehdrp->e_phnum > filesize / sizeof (Elf_External_Phdr))
+       goto got_wrong_format_error;
       elf_tdata (abfd)->phdr
        = (Elf_Internal_Phdr *) bfd_alloc2 (abfd, i_ehdrp->e_phnum,
                                            sizeof (*i_phdr));