From 4ace84a15ca943f52e590c264d82dfba350482e3 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 15 Dec 2023 12:24:56 +1030 Subject: PR31145, potential memory leak in binutils/ld PR 31145 * bfd.c (BFD_IN_MEMORY): Mention that bim is malloc'd. * format.c (io_reinit): Free BFD_IN_MEMORY iostream. * opncls.c (_bfd_delete_bfd): Likewise. (bfd_make_readable): Delete unnecessary code. * bfd-in2.h: Regenerate. --- bfd/bfd-in2.h | 4 ++-- bfd/bfd.c | 4 ++-- bfd/format.c | 9 ++++++++- bfd/opncls.c | 3 ++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 040d556..2807e69 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2035,8 +2035,8 @@ struct bfd #define BFD_TRADITIONAL_FORMAT 0x400 /* This flag indicates that the BFD contents are actually cached - in memory. If this is set, iostream points to a bfd_in_memory - struct. */ + in memory. If this is set, iostream points to a malloc'd + bfd_in_memory struct. */ #define BFD_IN_MEMORY 0x800 /* This BFD has been created by the linker and doesn't correspond diff --git a/bfd/bfd.c b/bfd/bfd.c index 616ded3..a5df4ef 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -160,8 +160,8 @@ CODE_FRAGMENT .#define BFD_TRADITIONAL_FORMAT 0x400 . . {* This flag indicates that the BFD contents are actually cached -. in memory. If this is set, iostream points to a bfd_in_memory -. struct. *} +. in memory. If this is set, iostream points to a malloc'd +. bfd_in_memory struct. *} .#define BFD_IN_MEMORY 0x800 . . {* This BFD has been created by the linker and doesn't correspond diff --git a/bfd/format.c b/bfd/format.c index 66dc2e7..31aeb52 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -166,7 +166,14 @@ io_reinit (bfd *abfd, struct bfd_preserve *preserve) won't do anything unless abfd->iovec is the cache_iovec. */ bfd_cache_close (abfd); abfd->iovec = preserve->iovec; - abfd->iostream = preserve->iostream; + + if (abfd->iostream != preserve->iostream) + { + if ((abfd->flags & BFD_IN_MEMORY) != 0) + free (abfd->iostream); + abfd->iostream = preserve->iostream; + } + /* Handle in-memory to file backed transition. */ if ((abfd->flags & BFD_CLOSED_BY_CACHE) != 0 && (abfd->flags & BFD_IN_MEMORY) != 0 diff --git a/bfd/opncls.c b/bfd/opncls.c index 5a77562..e7b3959 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -176,6 +176,8 @@ _bfd_delete_bfd (bfd *abfd) else free ((char *) bfd_get_filename (abfd)); + if ((abfd->flags & BFD_IN_MEMORY) != 0) + free (abfd->iostream); free (abfd->arelt_data); free (abfd); } @@ -1064,7 +1066,6 @@ bfd_make_readable (bfd *abfd) abfd->section_count = 0; abfd->usrdata = NULL; abfd->cacheable = false; - abfd->flags |= BFD_IN_MEMORY; abfd->mtime_set = false; abfd->target_defaulted = true; -- cgit v1.1