public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Commit: Add checks for overflowing 4Gb archive symbol table limit
@ 2012-07-03 16:24 Nick Clifton
  0 siblings, 0 replies; only message in thread
From: Nick Clifton @ 2012-07-03 16:24 UTC (permalink / raw)
  To: binutils

Hi Guys,

  I am applying the patch below to catch a problem with ar creating
  invalid archives (because the file offsets in the symbol table overflow
  the 32-bits that are available to them).  This is not just a
  theoretical problem - it has now started happening with real libraries
  in real production systems.

  As a side effect of the patch I have also extended readelf's dumping
  of archive symbol tables to include the file offset to the member
  containing the symbols.  This is useful to help track down problems
  like the file offsets overflowing 32-bits.

Cheers
  Nick

bfd/ChangeLog
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.

binutils/ChangeLog
2012-07-03  Nick Clifton  <nickc@redhat.com>

	* readelf.c (process_archive): Display member indicies when
	dumping index.

Index: bfd/archive.c
===================================================================
RCS file: /cvs/src/src/bfd/archive.c,v
retrieving revision 1.85
diff -u -3 -p -r1.85 archive.c
--- bfd/archive.c	29 Jun 2012 17:36:21 -0000	1.85
+++ bfd/archive.c	3 Jul 2012 14:28:56 -0000
@@ -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++;
 	}
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.576
diff -u -3 -p -r1.576 readelf.c
--- binutils/readelf.c	29 Jun 2012 07:02:36 -0000	1.576
+++ binutils/readelf.c	3 Jul 2012 14:28:58 -0000
@@ -13459,7 +13459,8 @@ process_archive (char * file_name, FILE 
 
                       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);
 		        }
 		    }


  

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-07-03 16:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-03 16:24 Commit: Add checks for overflowing 4Gb archive symbol table limit Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).