asan: _bfd_pei_slurp_codeview_record use of uninit value

Message ID 20200629010333.GD30281@bubble.grove.modra.org
State New
Headers show
Series
  • asan: _bfd_pei_slurp_codeview_record use of uninit value
Related show

Commit Message

Alan Modra via Binutils June 29, 2020, 1:03 a.m.
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.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index b3b68085dd..5149ef582b 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -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;