+2012-07-03 Nick Clifton <nickc@redhat.com>
+
+ * archive.c (bsd_write_armap): Catch attempts to create an archive
+ with indicies bigger than 4Gb.
+ (coff_write_armap): Likewise.
+
2012-07-03 H.J. Lu <hongjiu.lu@intel.com>
PR binutils/14319
unsigned int count;
struct ar_hdr hdr;
long uid, gid;
+ file_ptr max_first_real = 1;
+
+ max_first_real <<= 31;
firstreal = mapsize + elength + sizeof (struct ar_hdr) + SARMAG;
while (current != map[count].u.abfd);
}
+ /* The archive file format only has 4 bytes to store the offset
+ of the member. Check to make sure that firstreal has not grown
+ too big. */
+ if (firstreal >= max_first_real)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+
last_elt = current;
H_PUT_32 (arch, map[count].namidx, buf);
H_PUT_32 (arch, firstreal, buf + BSD_SYMDEF_OFFSET_SIZE);
unsigned int ranlibsize = (symbol_count * 4) + 4;
unsigned int stringsize = stridx;
unsigned int mapsize = stringsize + ranlibsize;
- unsigned int archive_member_file_ptr;
+ file_ptr archive_member_file_ptr;
bfd *current = arch->archive_head;
unsigned int count;
struct ar_hdr hdr;
while (count < symbol_count && map[count].u.abfd == current)
{
- if (!bfd_write_bigendian_4byte_int (arch, archive_member_file_ptr))
+ unsigned int offset = (unsigned int) archive_member_file_ptr;
+
+ /* Catch an attempt to grow an archive past its 4Gb limit. */
+ if (archive_member_file_ptr != (file_ptr) offset)
+ {
+ bfd_set_error (bfd_error_file_truncated);
+ return FALSE;
+ }
+ if (!bfd_write_bigendian_4byte_int (arch, offset))
return FALSE;
count++;
}
if (qualified_name != NULL)
{
- printf (_("Binary %s contains:\n"), qualified_name);
+ printf (_("Binary %s at offset 0x%lx contains:\n"),
+ qualified_name, arch.index_array[i]);
free (qualified_name);
}
}