aboutsummaryrefslogtreecommitdiff
path: root/ld/emultempl
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2020-05-18 10:28:52 +0100
committerNick Clifton <nickc@redhat.com>2020-05-18 10:28:52 +0100
commit5e365e474b7561318ddb1a107f05cf0c002e8284 (patch)
tree20043016f5da4a290056532ed6d88a0dc264c3a1 /ld/emultempl
parentd402189f2faa0aaa9fb8ad4669fdf0059946cd8a (diff)
downloadfsf-binutils-gdb-5e365e474b7561318ddb1a107f05cf0c002e8284.zip
fsf-binutils-gdb-5e365e474b7561318ddb1a107f05cf0c002e8284.tar.gz
fsf-binutils-gdb-5e365e474b7561318ddb1a107f05cf0c002e8284.tar.bz2
Prevent a potential use-after-fee memory corruption bug in the linker (for PE format files).
PR 25993 * emultempl/pe.em (_after_open): Check for duplicate filename pointers before renaming the dll. * emultempl/pep.em (_after_open): Likewise.
Diffstat (limited to 'ld/emultempl')
-rw-r--r--ld/emultempl/pe.em26
-rw-r--r--ld/emultempl/pep.em25
2 files changed, 39 insertions, 12 deletions
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 4fe195e..ad5d65d 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -1655,13 +1655,27 @@ 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);
- new_name = xmalloc (strlen (is->filename) + 3);
- sprintf (new_name, "%s.%c", is->filename, seq);
- is->filename = 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;
+ }
}
}
}
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index 3e03eb3..aa8bac5 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -1623,13 +1623,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;
+ }
}
}
}