]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Prevent a potential use-after-fee memory corruption bug in the linker (for PE format...
authorNick Clifton <nickc@redhat.com>
Wed, 3 Jun 2020 14:16:48 +0000 (15:16 +0100)
committerNick Clifton <nickc@redhat.com>
Wed, 3 Jun 2020 14:16:48 +0000 (15:16 +0100)
PR 25993
* emultempl/pe.em (_after_open): Check for duplicate filename
pointers before renaming the dll.
* emultempl/pep.em (_after_open): Likewise.

ld/ChangeLog
ld/emultempl/pe.em
ld/emultempl/pep.em

index f26bea4fcfde88eabcf286f4632dd44e0e955a5a..0006ace73e6fbeb47425d6468b845a1180c3edc5 100644 (file)
@@ -1,3 +1,13 @@
+2020-06-03  Nick Clifton  <nickc@redhat.com>
+
+       Import from mainline:
+       2020-05-18  Nick Clifton  <nickc@redhat.com>
+
+       PR 25993
+       * emultempl/pe.em (_after_open): Check for duplicate filename
+       pointers before renaming the dll.
+       * emultempl/pep.em (_after_open): Likewise.
+
 2020-04-08  Tamar Christina  <tamar.christina@arm.com>
 
        Backport from mainline.
index 97fb1468aac92ecb11df16191c03a435bbcf6326..26fa7465c0965d18cfe505f0693d1a223bf43eb1 100644 (file)
@@ -1652,13 +1652,26 @@ gld_${EMULATION_NAME}_after_open (void)
                else /* sentinel */
                  seq = 'c';
 
-               new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
-               sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
-               bfd_set_filename (is->the_bfd, new_name);
+               /* PR 25993: It is possible that is->the_bfd-filename == is->filename.
+                  In which case calling bfd_set_filename on one will free the memory
+                  pointed to by the other.  */
+               if (is->filename == is->the_bfd->filename)
+                 {
+                   new_name = xmalloc (strlen (is->filename) + 3);
+                   sprintf (new_name, "%s.%c", is->filename, seq);
+                   bfd_set_filename (is->the_bfd, new_name);
+                   is->filename = new_name;
+                 }
+               else
+                 {
+                   new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
+                   sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
+                   bfd_set_filename (is->the_bfd, new_name);
 
-               new_name = xmalloc (strlen (is->filename) + 3);
-               sprintf (new_name, "%s.%c", is->filename, seq);
-               is->filename = new_name;
+                   new_name = xmalloc (strlen (is->filename) + 3);
+                   sprintf (new_name, "%s.%c", is->filename, seq);
+                   is->filename = new_name;
+                 }
              }
          }
       }
index e8f5ca503fb5695acd95d240da98e574b5095d69..ef23221c03bc69d48a2b531c85c0528791a60ec7 100644 (file)
@@ -1620,13 +1620,26 @@ gld_${EMULATION_NAME}_after_open (void)
                else /* sentinel */
                  seq = 'c';
 
-               new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
-               sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
-               bfd_set_filename (is->the_bfd, new_name);
+               /* PR 25993: It is possible that is->the_bfd-filename == is->filename.
+                  In which case calling bfd_set_filename on one will free the memory
+                  pointed to by the other.  */
+               if (is->filename == is->the_bfd->filename)
+                 {
+                   new_name = xmalloc (strlen (is->filename) + 3);
+                   sprintf (new_name, "%s.%c", is->filename, seq);
+                   bfd_set_filename (is->the_bfd, new_name);
+                   is->filename = new_name;
+                 }
+               else
+                 {
+                   new_name = xmalloc (strlen (is->the_bfd->filename) + 3);
+                   sprintf (new_name, "%s.%c", is->the_bfd->filename, seq);
+                   bfd_set_filename (is->the_bfd, new_name);
 
-               new_name = xmalloc (strlen (is->filename) + 3);
-               sprintf (new_name, "%s.%c", is->filename, seq);
-               is->filename = new_name;
+                   new_name = xmalloc (strlen (is->filename) + 3);
+                   sprintf (new_name, "%s.%c", is->filename, seq);
+                   is->filename = new_name;
+                 }
              }
          }
       }