summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2020-06-03 15:16:48 +0100
committerNick Clifton <nickc@redhat.com>2020-06-03 15:16:48 +0100
commit463ec189fe9eca199edf87cda2c31efbe850390d (patch)
tree076aac9275d4f22d28d929e4a101b99cfa653e0f
parent1a4d543e78c4b1d6739d931a428e2284abd85382 (diff)
downloadbinutils-gdb-463ec189fe9eca199edf87cda2c31efbe850390d.tar.gz
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.
-rw-r--r--ld/ChangeLog10
-rw-r--r--ld/emultempl/pe.em25
-rw-r--r--ld/emultempl/pep.em25
3 files changed, 48 insertions, 12 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index f26bea4fcfd..0006ace73e6 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -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.
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 97fb1468aac..26fa7465c09 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -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;
+ }
}
}
}
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index e8f5ca503fb..ef23221c03b 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -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;
+ }
}
}
}