[binutils-gdb] Re: ld plugin bfd_make_readable leak

Alan Modra amodra@sourceware.org
Sat Jan 25 00:23:49 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=314b99ee71e37919a9e67b5caf4448d1db5f04b0

commit 314b99ee71e37919a9e67b5caf4448d1db5f04b0
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Jan 25 10:15:58 2025 +1030

    Re: ld plugin bfd_make_readable leak
    
    Commit 3097045a18a8 runs into an abort in objalloc_free_block when the
    memory being bfd_release'd wasn't bfd_alloc'd.  Fix that.
    
            * coffgen.c (_bfd_coff_free_cached_info): Don't release
            raw_syments when obj_coff_keep_raw_syms.
            * libcoff-in.h (obj_coff_keep_raw_syms): Define.
            (struct coff_tdata): Add keep_raw_syms.
            * peicode.h (pe_ILF_build_a_bfd): Set obj_coff_keep_raw_syms.
            * libcoff.h: Regenerate.

Diff:
---
 bfd/coffgen.c    | 12 +++++++-----
 bfd/libcoff-in.h |  3 +++
 bfd/libcoff.h    |  3 +++
 bfd/peicode.h    |  1 +
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index c4026e96afb..c734f058892 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -3299,11 +3299,13 @@ _bfd_coff_free_cached_info (bfd *abfd)
 
       /* Free raw syms, and any other data bfd_alloc'd after raw syms
 	 are read.  */
-      if (obj_raw_syments (abfd))
-	bfd_release (abfd, obj_raw_syments (abfd));
-      obj_raw_syments (abfd) = NULL;
-      obj_symbols (abfd) = NULL;
-      obj_convert (abfd) = NULL;
+      if (!obj_coff_keep_raw_syms (abfd) && obj_raw_syments (abfd))
+	{
+	  bfd_release (abfd, obj_raw_syments (abfd));
+	  obj_raw_syments (abfd) = NULL;
+	  obj_symbols (abfd) = NULL;
+	  obj_convert (abfd) = NULL;
+	}
     }
 
   return _bfd_generic_bfd_free_cached_info (abfd);
diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index 51f964c4fd2..1410b08f6ae 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -40,6 +40,7 @@ extern "C" {
 #define obj_relocbase(bfd)	      (coff_data (bfd)->relocbase)
 #define obj_raw_syments(bfd)	      (coff_data (bfd)->raw_syments)
 #define obj_raw_syment_count(bfd)     (coff_data (bfd)->raw_syment_count)
+#define obj_coff_keep_raw_syms(bfd)   (coff_data (bfd)->keep_raw_syms)
 #define obj_convert(bfd)	      (coff_data (bfd)->conversion_table)
 #define obj_conv_table_size(bfd)      (coff_data (bfd)->conv_table_size)
 #define obj_coff_external_syms(bfd)   (coff_data (bfd)->external_syms)
@@ -91,6 +92,8 @@ typedef struct coff_tdata
      backend flag _bfd_coff_long_section_names.  */
   bool long_section_names;
 
+  /* If this is TRUE, raw_syments may not be released.  */
+  bool keep_raw_syms;
   /* If this is TRUE, the external_syms may not be freed.  */
   bool keep_syms;
   /* If this is TRUE, the strings may not be freed.  */
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index 947dbeb67a0..d0cfd09709a 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -44,6 +44,7 @@ extern "C" {
 #define obj_relocbase(bfd)	      (coff_data (bfd)->relocbase)
 #define obj_raw_syments(bfd)	      (coff_data (bfd)->raw_syments)
 #define obj_raw_syment_count(bfd)     (coff_data (bfd)->raw_syment_count)
+#define obj_coff_keep_raw_syms(bfd)   (coff_data (bfd)->keep_raw_syms)
 #define obj_convert(bfd)	      (coff_data (bfd)->conversion_table)
 #define obj_conv_table_size(bfd)      (coff_data (bfd)->conv_table_size)
 #define obj_coff_external_syms(bfd)   (coff_data (bfd)->external_syms)
@@ -95,6 +96,8 @@ typedef struct coff_tdata
      backend flag _bfd_coff_long_section_names.  */
   bool long_section_names;
 
+  /* If this is TRUE, raw_syments may not be released.  */
+  bool keep_raw_syms;
   /* If this is TRUE, the external_syms may not be freed.  */
   bool keep_syms;
   /* If this is TRUE, the strings may not be freed.  */
diff --git a/bfd/peicode.h b/bfd/peicode.h
index ad4f1963b9c..3a93e008799 100644
--- a/bfd/peicode.h
+++ b/bfd/peicode.h
@@ -1154,6 +1154,7 @@ pe_ILF_build_a_bfd (bfd *	    abfd,
 
   obj_raw_syments (abfd) = vars.native_syms;
   obj_raw_syment_count (abfd) = vars.sym_index;
+  obj_coff_keep_raw_syms (abfd) = true;
 
   obj_coff_external_syms (abfd) = (void *) vars.esym_table;
   obj_coff_keep_syms (abfd) = true;


More information about the Binutils-cvs mailing list