This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix 64 bit archives


Hi,
This patch fixes a buffer overrun when generating the symbol map for a 64bit archive. There are two loops, the outer one has a check for 'count < limit', but the inner one is responsible for incrementing count as it steps over a variable length run of symbols. Unfortunately it fails to check for buffer end, and instead terminates when the abfd value changes. Mostly this also changes after the end of the buffer, but sometimes it doesn't, and that leads to dumping out too many addresses and consequently ending up with a corrupt archive.


I took the opportunity to make the looping structure more obvious by using for loops rather than while loops.

built & tested on mips-linux.

ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

2010-06-23  Nathan Sidwell  <nathan@codesourcery.com>

	* archive64.c (bfd_elf64_archive_write_armap): Fix buffer overrun
	when scaning map.

Index: bfd/archive64.c
===================================================================
--- bfd/archive64.c	(revision 290407)
+++ bfd/archive64.c	(working copy)
@@ -196,27 +196,27 @@ bfd_elf64_archive_write_armap (bfd *arch
 
   /* Write out the file offset for the file associated with each
      symbol, and remember to keep the offsets padded out.  */
-
-  current = arch->archive_head;
   count = 0;
-  while (current != NULL && count < symbol_count)
+  for (current = arch->archive_head;
+       current != NULL && count < symbol_count;
+       current = current->archive_next)
     {
       /* For each symbol which is used defined in this object, write out
 	 the object file's address in the archive */
 
-      while (map[count].u.abfd == current)
+      for (;
+	   count < symbol_count && map[count].u.abfd == current;
+	   count++)
 	{
 	  bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
 	  if (bfd_bwrite (buf, 8, arch) != 8)
 	    return FALSE;
-	  count++;
 	}
       /* Add size of this archive entry */
       archive_member_file_ptr += (arelt_size (current)
 				  + sizeof (struct ar_hdr));
       /* remember about the even alignment */
       archive_member_file_ptr += archive_member_file_ptr % 2;
-      current = current->archive_next;
     }
 
   /* now write the strings themselves */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]