Sanity check _bfd_coff_read_string_table
authorAlan Modra <amodra@gmail.com>
Fri, 30 Jul 2021 03:26:22 +0000 (12:56 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 30 Jul 2021 05:36:56 +0000 (15:06 +0930)
* coffgen.c (_bfd_coff_read_string_table): Catch overflows
when calculating string table file location.

bfd/coffgen.c

index 017d4c31a4e61b50dade6fcc8305c62e62f87fe1..ca93682846848fb34602938fe4fc19ad668699dd 100644 (file)
@@ -1662,8 +1662,10 @@ _bfd_coff_read_string_table (bfd *abfd)
   char extstrsize[STRING_SIZE_SIZE];
   bfd_size_type strsize;
   char *strings;
-  file_ptr pos;
+  ufile_ptr pos;
   ufile_ptr filesize;
+  size_t symesz;
+  size_t size;
 
   if (obj_coff_strings (abfd) != NULL)
     return obj_coff_strings (abfd);
@@ -1674,9 +1676,16 @@ _bfd_coff_read_string_table (bfd *abfd)
       return NULL;
     }
 
+  symesz = bfd_coff_symesz (abfd);
   pos = obj_sym_filepos (abfd);
-  pos += obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd);
-  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
+  if (_bfd_mul_overflow (obj_raw_syment_count (abfd), symesz, &size)
+      || pos + size < pos)
+    {
+      bfd_set_error (bfd_error_file_truncated);
+      return NULL;
+    }
+
+  if (bfd_seek (abfd, pos + size, SEEK_SET) != 0)
     return NULL;
 
   if (bfd_bread (extstrsize, (bfd_size_type) sizeof extstrsize, abfd)