diff options
author | Nick Clifton <nickc@redhat.com> | 2012-07-03 16:25:17 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2012-07-03 16:25:17 +0000 |
commit | 5f8ebec53d47aacc4dc1d67f3c9b0117539b2468 (patch) | |
tree | 9e8782d177aba96110ec1d0ab0bb3af0b7e727eb /bfd/archive.c | |
parent | 00595b5e791b2326344340ad568e76c05b3ad402 (diff) | |
download | gdb-5f8ebec53d47aacc4dc1d67f3c9b0117539b2468.zip gdb-5f8ebec53d47aacc4dc1d67f3c9b0117539b2468.tar.gz gdb-5f8ebec53d47aacc4dc1d67f3c9b0117539b2468.tar.bz2 |
* archive.c (bsd_write_armap): Catch attempts to create an archive
with indicies bigger than 4Gb.
(coff_write_armap): Likewise.
* readelf.c (process_archive): Display member indicies when
dumping index.
Diffstat (limited to 'bfd/archive.c')
-rw-r--r-- | bfd/archive.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/bfd/archive.c b/bfd/archive.c index 0620452..f56e99e 100644 --- a/bfd/archive.c +++ b/bfd/archive.c @@ -2405,6 +2405,9 @@ bsd_write_armap (bfd *arch, 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; @@ -2463,6 +2466,15 @@ bsd_write_armap (bfd *arch, 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); @@ -2574,7 +2586,7 @@ coff_write_armap (bfd *arch, 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; @@ -2625,7 +2637,15 @@ coff_write_armap (bfd *arch, 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++; } |