diff options
author | Nick Clifton <nickc@redhat.com> | 2020-05-18 10:28:52 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2020-05-18 10:28:52 +0100 |
commit | 5e365e474b7561318ddb1a107f05cf0c002e8284 (patch) | |
tree | 20043016f5da4a290056532ed6d88a0dc264c3a1 /ld | |
parent | d402189f2faa0aaa9fb8ad4669fdf0059946cd8a (diff) | |
download | gdb-5e365e474b7561318ddb1a107f05cf0c002e8284.zip gdb-5e365e474b7561318ddb1a107f05cf0c002e8284.tar.gz 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')
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/emultempl/pe.em | 26 | ||||
-rw-r--r-- | ld/emultempl/pep.em | 25 |
3 files changed, 46 insertions, 12 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 5923e4c..49c6970 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +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-05-13 Nick Clifton <nickc@redhat.com> PR 25979 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; + } } } } |