* archive.c (bsd_write_armap): Catch attempts to create an archive
authorNick Clifton <nickc@redhat.com>
Tue, 3 Jul 2012 16:25:17 +0000 (16:25 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 3 Jul 2012 16:25:17 +0000 (16:25 +0000)
with indicies bigger than 4Gb.
(coff_write_armap): Likewise.

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

bfd/ChangeLog
bfd/archive.c
binutils/ChangeLog
binutils/readelf.c

index 5ab85252b512c5b3a4ac6565c4e49b3a1efd9326..f6d368e3a3daf509ad7d2434783a829f3685d8e4 100644 (file)
@@ -1,3 +1,9 @@
+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
index 062045263a1b10f7b8b97394394ff0697af16513..f56e99e8dd8266a6c0e3ac57f5785cd508d5f813 100644 (file)
@@ -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 f0ab054e231a4a13907c4aaa4232668d90533e50..7c3018f4326e898cbd6bfa896d8aa9e4f19d0803 100644 (file)
@@ -1,3 +1,8 @@
+2012-07-03  Nick Clifton  <nickc@redhat.com>
+
+       * readelf.c (process_archive): Display member indicies when
+       dumping index.
+
 2012-07-02  Tom Tromey  <tromey@redhat.com>
 
        * dwarf.c: Include gdb-index.h.
index b1bacfd722778efad76a1d4fd512c71a19f28495..2fcd5827d6540251c517fb39f86f6f9f54a43d00 100644 (file)
@@ -13459,7 +13459,8 @@ process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
 
                       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);
                        }
                    }