]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Prevent looping in archives
authorAlan Modra <amodra@gmail.com>
Wed, 18 Nov 2015 11:42:23 +0000 (22:12 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 10 Dec 2015 13:47:41 +0000 (00:17 +1030)
PR 19256
* archive.c (bfd_generic_openr_next_archived_file): Don't allow
backward file movement via "negative" sizes.
* coff-alpha.c (alpha_ecoff_openr_next_archived_file): Likewise.

bfd/ChangeLog
bfd/archive.c
bfd/coff-alpha.c

index 7b2dd0a13f5e6c46521400247840ce168cc8cbd8..80a5b2def8df17d8b6cb7f69430aa6c2d5d4941b 100644 (file)
@@ -1,3 +1,12 @@
+2015-12-10  Alan Modra  <amodra@gmail.com>
+
+       Apply from master.
+       2015-11-18  Alan Modra  <amodra@gmail.com>
+       PR 19256
+       * archive.c (bfd_generic_openr_next_archived_file): Don't allow
+       backward file movement via "negative" sizes.
+       * coff-alpha.c (alpha_ecoff_openr_next_archived_file): Likewise.
+
 2015-12-04  H.J. Lu  <hongjiu.lu@intel.com>
 
        * elf32-i386.c (elf_i386_convert_load): Skip if addend isn't 0.
index 1715474ea6cecd9bcdb8378bdf933036139843d6..b3d03d36daf62ddfa40d33fd9bb489172c29c630 100644 (file)
@@ -786,21 +786,29 @@ bfd_openr_next_archived_file (bfd *archive, bfd *last_file)
 bfd *
 bfd_generic_openr_next_archived_file (bfd *archive, bfd *last_file)
 {
-  file_ptr filestart;
+  ufile_ptr filestart;
 
   if (!last_file)
     filestart = bfd_ardata (archive)->first_file_filepos;
   else
     {
-      bfd_size_type size = arelt_size (last_file);
-
       filestart = last_file->proxy_origin;
       if (! bfd_is_thin_archive (archive))
-       filestart += size;
-      /* Pad to an even boundary...
-        Note that last_file->origin can be odd in the case of
-        BSD-4.4-style element with a long odd size.  */
-      filestart += filestart % 2;
+       {
+         bfd_size_type size = arelt_size (last_file);
+
+         filestart += size;
+         /* Pad to an even boundary...
+            Note that last_file->origin can be odd in the case of
+            BSD-4.4-style element with a long odd size.  */
+         filestart += filestart % 2;
+         if (filestart <= last_file->proxy_origin)
+           {
+             /* Prevent looping.  See PR19256.  */
+             bfd_set_error (bfd_error_malformed_archive);
+             return NULL;
+           }
+       }
     }
 
   return _bfd_get_elt_at_filepos (archive, filestart);
index 58d4e1d1fbe536db2255cd811baa24d0e4ddef70..7478f2f320d39a81f2d390de36ce44b42fd756ba 100644 (file)
@@ -2187,7 +2187,7 @@ alpha_ecoff_get_elt_at_filepos (bfd *archive, file_ptr filepos)
 static bfd *
 alpha_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file)
 {
-  file_ptr filestart;
+  ufile_ptr filestart;
 
   if (last_file == NULL)
     filestart = bfd_ardata (archive)->first_file_filepos;
@@ -2208,6 +2208,12 @@ alpha_ecoff_openr_next_archived_file (bfd *archive, bfd *last_file)
         BSD-4.4-style element with a long odd size.  */
       filestart = last_file->proxy_origin + size;
       filestart += filestart % 2;
+      if (filestart <= last_file->proxy_origin)
+       {
+         /* Prevent looping.  See PR19256.  */
+         bfd_set_error (bfd_error_malformed_archive);
+         return NULL;
+       }
     }
 
   return alpha_ecoff_get_elt_at_filepos (archive, filestart);