asan: _bfd_pei_slurp_codeview_record use of uninit value
authorAlan Modra <amodra@gmail.com>
Mon, 29 Jun 2020 00:21:07 +0000 (09:51 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 29 Jun 2020 00:39:14 +0000 (10:09 +0930)
Fixes some seriously careless code.  bfd_bread return value is
(bfd_size_type)-1 on error.  "if (bfd_bread (...) < 4)" does not check
for an error since bfd_size_type is unsigned.  In any case, I think we
should be reading and checking the requested length.

* peXXigen.c (_bfd_XXi_slurp_codeview_record): Properly check
return value of bfd_bread.  Don't read more than requested length.
Sanity check length.  Properly terminate file name.

bfd/ChangeLog
bfd/peXXigen.c

index 4a87b3bb5c2f4bc3afe888b502d3f9a8aa6cb856..1bf65c294d69607270a17dc2149bb2e7e3656895 100644 (file)
@@ -1,3 +1,9 @@
+2020-06-29  Alan Modra  <amodra@gmail.com>
+
+       * peXXigen.c (_bfd_XXi_slurp_codeview_record): Properly check
+       return value of bfd_bread.  Don't read more than requested length.
+       Sanity check length.  Properly terminate file name.
+
 2020-06-29  Alan Modra  <amodra@gmail.com>
 
        * arc-got.h: Use C style comments.
index b3b68085ddcaaf9cb64cded9215a74f219678a5c..5149ef582bf6dea0ad176e441b0041ae4234248a 100644 (file)
@@ -1147,15 +1147,21 @@ CODEVIEW_INFO *
 _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo)
 {
   char buffer[256+1];
+  bfd_size_type nread;
 
   if (bfd_seek (abfd, where, SEEK_SET) != 0)
     return NULL;
 
-  if (bfd_bread (buffer, 256, abfd) < 4)
+  if (length <= sizeof (CV_INFO_PDB70) && length <= sizeof (CV_INFO_PDB20))
+    return NULL;
+  if (length > 256)
+    length = 256;
+  nread = bfd_bread (buffer, length, abfd);
+  if (length != nread)
     return NULL;
 
   /* Ensure null termination of filename.  */
-  buffer[256] = '\0';
+  memset (buffer + nread, 0, sizeof (buffer) - nread);
 
   cvinfo->CVSignature = H_GET_32 (abfd, buffer);
   cvinfo->Age = 0;