diff options
author | Alan Modra <amodra@gmail.com> | 2017-08-31 08:46:47 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-08-31 10:30:07 +0930 |
commit | e234de6be5cc96286e0efb90e8d9fce51239e901 (patch) | |
tree | 51026a979501f87cc616f77feb578ce31ad2124b | |
parent | e69f32654ac724c46c0f4f645c8a49189c7b43e4 (diff) | |
download | gdb-e234de6be5cc96286e0efb90e8d9fce51239e901.zip gdb-e234de6be5cc96286e0efb90e8d9fce51239e901.tar.gz gdb-e234de6be5cc96286e0efb90e8d9fce51239e901.tar.bz2 |
bfd_close_all_done calling _close_and_cleanup
elf64_vms_close_and_cleanup calls bfd_get_size, which calls
iovec->bstat. cache_bstat ends up adding the bfd to the cache lru
list, negating the bfd_cache_close call in bfd_close_all_done. So
there is a dangling pointer into the freed and then reused bfd. Thus,
bfd_cache_close must be called after _close_and_cleanup, or better,
via iovec->bclose.
PR binutils/22032
* opncls.c (bfd_close_all_done): Don't call bfd_cache_close
before _close_and_cleanup. Call iovec->bclose after.
(bfd_close): Remove code common to, and call, bfd_close_all_done.
-rw-r--r-- | bfd/ChangeLog | 7 | ||||
-rw-r--r-- | bfd/opncls.c | 18 |
2 files changed, 10 insertions, 15 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index bda958a..52a88f8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2017-08-31 Alan Modra <amodra@gmail.com> + + PR binutils/22032 + * opncls.c (bfd_close_all_done): Don't call bfd_cache_close + before _close_and_cleanup. Call iovec->bclose after. + (bfd_close): Remove code common to, and call, bfd_close_all_done. + 2017-08-30 H.J. Lu <hongjiu.lu@intel.com> * elf32-i386.c (elf_i386_plt_type): Removed. diff --git a/bfd/opncls.c b/bfd/opncls.c index b99ae72..fa54986 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -726,25 +726,13 @@ RETURNS bfd_boolean bfd_close (bfd *abfd) { - bfd_boolean ret; - if (bfd_write_p (abfd)) { if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd))) return FALSE; } - if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) - return FALSE; - - ret = abfd->iovec->bclose (abfd) == 0; - - if (ret) - _maybe_make_executable (abfd); - - _bfd_delete_bfd (abfd); - - return ret; + return bfd_close_all_done (abfd); } /* @@ -774,11 +762,11 @@ bfd_close_all_done (bfd *abfd) { bfd_boolean ret; - ret = bfd_cache_close (abfd); - if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) return FALSE; + ret = abfd->iovec->bclose (abfd) == 0; + if (ret) _maybe_make_executable (abfd); |