This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
fix 64 bit archives
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils <binutils at sourceware dot org>
- Date: Wed, 23 Jun 2010 10:34:23 +0100
- Subject: 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 */