public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] elf: Fix a memory leak in _bfd_elf_add_dynamic_entry
@ 2024-04-11  2:52 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 2024-04-11  2:52 UTC (permalink / raw)
  To: binutils-cvs

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

commit c3460201a64b641e3a2089b7fca7ae17a9ddfb85
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Apr 9 18:41:59 2024 -0700

    elf: Fix a memory leak in _bfd_elf_add_dynamic_entry
    
    Normally, the section contents is allocated by bfd_alloc which is freed
    when the object is closed.  But the .dynamic section contents is allocated
    by bfd_realloc, which should be freed by calling free.  Add a dynamic
    field to elf_link_hash_table for the .dynamic section and free its
    contents in _bfd_elf_link_hash_table_free.
    
            * elf-bfd.h (elf_link_hash_table): Add dynamic.
            * elflink.c (_bfd_elf_link_create_dynamic_sections): Set the
            dynamic field in elf_link_hash_table.
            (_bfd_elf_add_dynamic_entry): Use hash_table->dynamic.
            (_bfd_elf_strip_zero_sized_dynamic_sections): Likewise.
            (bfd_elf_add_dt_needed_tag): Likewise.
            (elf_finalize_dynstr): Likewise.
            (_bfd_elf_link_hash_table_free): Free htab->dynamic->contents.
            (bfd_elf_final_link): Use htab->dynamic.
            * elfxx-x86.c (_bfd_x86_elf_finish_dynamic_sections): Use
            htab->elf.dynamic.

Diff:
---
 bfd/elf-bfd.h   |  1 +
 bfd/elflink.c   | 16 ++++++++++------
 bfd/elfxx-x86.c |  2 +-
 3 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 85e66488955..ef5dcb55e72 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -757,6 +757,7 @@ struct elf_link_hash_table
   asection *irelifunc;
   asection *dynsym;
   asection *srelrdyn;
+  asection *dynamic;
 };
 
 /* Returns TRUE if the hash table is a struct elf_link_hash_table.  */
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c73470276cd..22fddb8f56b 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -355,6 +355,7 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   if (s == NULL
       || !bfd_set_section_alignment (s, bed->s->log_file_align))
     return false;
+  elf_hash_table (info)->dynamic = s;
 
   /* The special symbol _DYNAMIC is always set to the start of the
      .dynamic section.  We could set _DYNAMIC in a linker script, but we
@@ -3729,7 +3730,7 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
     hash_table->dynamic_relocs = true;
 
   bed = get_elf_backend_data (hash_table->dynobj);
-  s = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+  s = hash_table->dynamic;
   BFD_ASSERT (s != NULL);
 
   newsize = s->size + bed->s->sizeof_dyn;
@@ -3772,7 +3773,7 @@ _bfd_elf_strip_zero_sized_dynamic_sections (struct bfd_link_info *info)
   if (!hash_table->dynobj)
     return true;
 
-  sdynamic= bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+  sdynamic= hash_table->dynamic;
   if (!sdynamic)
     return true;
 
@@ -3872,7 +3873,7 @@ bfd_elf_add_dt_needed_tag (bfd *abfd, struct bfd_link_info *info)
       bfd_byte *extdyn;
 
       bed = get_elf_backend_data (hash_table->dynobj);
-      sdyn = bfd_get_linker_section (hash_table->dynobj, ".dynamic");
+      sdyn = hash_table->dynamic;
       if (sdyn != NULL && sdyn->size != 0)
 	for (extdyn = sdyn->contents;
 	     extdyn < sdyn->contents + sdyn->size;
@@ -4017,7 +4018,7 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
     info->callbacks->examine_strtab (dynstr);
 
   bed = get_elf_backend_data (dynobj);
-  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+  sdyn = hash_table->dynamic;
   BFD_ASSERT (sdyn != NULL);
 
   /* Update all .dynamic entries referencing .dynstr strings.  */
@@ -8352,6 +8353,9 @@ _bfd_elf_link_hash_table_free (bfd *obfd)
   if (htab->dynstr != NULL)
     _bfd_elf_strtab_free (htab->dynstr);
   _bfd_merge_sections_free (htab->merge_info);
+  /* NB: htab->dynamic->contents is always allocated by bfd_realloc.  */
+  if (htab->dynamic != NULL)
+    free (htab->dynamic->contents);
   if (htab->first_hash != NULL)
     {
       bfd_hash_table_free (htab->first_hash);
@@ -13420,7 +13424,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       bfd_byte *dyncon, *dynconend;
 
       /* Fix up .dynamic entries.  */
-      o = bfd_get_linker_section (dynobj, ".dynamic");
+      o = htab->dynamic;
       BFD_ASSERT (o != NULL);
 
       dyncon = o->contents;
@@ -13654,7 +13658,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 
       /* Check for DT_TEXTREL (late, in case the backend removes it).  */
       if (bfd_link_textrel_check (info)
-	  && (o = bfd_get_linker_section (dynobj, ".dynamic")) != NULL
+	  && (o = htab->dynamic) != NULL
 	  && o->size != 0)
 	{
 	  bfd_byte *dyncon, *dynconend;
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 7d189bc66d1..725884e78c1 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -2715,7 +2715,7 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
     return htab;
 
   dynobj = htab->elf.dynobj;
-  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+  sdyn = htab->elf.dynamic;
 
   /* GOT is always created in setup_gnu_properties.  But it may not be
      needed.  .got.plt section may be needed for static IFUNC.  */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-11  2:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-11  2:52 [binutils-gdb] elf: Fix a memory leak in _bfd_elf_add_dynamic_entry H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).