This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] unstrip: Don't leak new section data.


When we copy elided sections some section data is newly allocated.
Track those allocations so we can free them when done.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 src/ChangeLog | 10 ++++++++++
 src/unstrip.c | 39 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 27c638f..be7768f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2015-12-02  Mark Wielaard  <mjw@redhat.com>
+
+	* unstrip.c (struct data_list): New.
+	(new_data_list): Likewise.
+	(record_new_data): Likewise.
+	(free_new_data): Likewise.
+	(adjust_relocs): Call record_new_data.
+	(add_new_section_symbols): Likewise.
+	(copy_elided_sections): Call free_new_data.
+
 2015-12-01  Mark Wielaard  <mjw@redhat.com>
 
 	* elfcmp.c (main): Close ebl1 and ebl2 backends.
diff --git a/src/unstrip.c b/src/unstrip.c
index bc8ed50..85e0a1d 100644
--- a/src/unstrip.c
+++ b/src/unstrip.c
@@ -311,6 +311,38 @@ make_directories (const char *path)
       error (EXIT_FAILURE, errno, _("cannot create directory '%s'"), dir);
 }
 
+/* Keep track of new section data we are creating, so we can free it
+   when done.  */
+struct data_list
+{
+  void *data;
+  struct data_list *next;
+};
+
+struct data_list *new_data_list;
+
+static void
+record_new_data (void *data)
+{
+  struct data_list *next = new_data_list;
+  new_data_list = xmalloc (sizeof (struct data_list));
+  new_data_list->data = data;
+  new_data_list->next = next;
+}
+
+static void
+free_new_data (void)
+{
+  struct data_list *list = new_data_list;
+  while (list != NULL)
+    {
+      struct data_list *next = list->next;
+      free (list->data);
+      free (list);
+      list = next;
+    }
+  new_data_list = NULL;
+}
 
 /* The binutils linker leaves gratuitous section symbols in .symtab
    that strip has to remove.  Older linkers likewise include a
@@ -472,6 +504,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
 	    if (old_chain[i] != STN_UNDEF)				      \
 	      new_chain[map[i - 1]] = map[old_chain[i] - 1];		      \
 									      \
+	  record_new_data (new_hash);					\
 	  data->d_buf = new_hash;					      \
 	  data->d_size = nent * sizeof new_hash[0];			      \
 	}
@@ -514,6 +547,7 @@ adjust_relocs (Elf_Scn *outscn, Elf_Scn *inscn, const GElf_Shdr *shdr,
 	    ELF_CHECK (v != NULL, _("cannot get symbol version: %s"));
 	  }
 
+	record_new_data (versym);
 	data->d_buf = versym;
 	data->d_size = nent * shdr->sh_entsize;
 	elf_flagdata (data, ELF_C_SET, ELF_F_DIRTY);
@@ -571,6 +605,7 @@ add_new_section_symbols (Elf_Scn *old_symscn, size_t old_shnum,
 
   symdata->d_size = shdr->sh_size;
   symdata->d_buf = xmalloc (symdata->d_size);
+  record_new_data (symdata->d_buf);
 
   /* Copy the existing section symbols.  */
   Elf_Data *old_symdata = elf_getdata (old_symscn, NULL);
@@ -1762,6 +1797,7 @@ more sections in stripped file than debug file -- arguments reversed?"));
 
       shdr->sh_size = symdata->d_size = (1 + nsym) * shdr->sh_entsize;
       symdata->d_buf = xmalloc (symdata->d_size);
+      record_new_data (symdata->d_buf);
 
       GElf_Sym sym;
       memset (&sym, 0, sizeof sym);
@@ -1927,13 +1963,12 @@ more sections in stripped file than debug file -- arguments reversed?"));
       free (strtab_data->d_buf);
     }
 
-  if (symdata != NULL)
-    free (symdata->d_buf);
   if (symstrtab != NULL)
     {
       ebl_strtabfree (symstrtab);
       free (symstrdata->d_buf);
     }
+  free_new_data ();
 }
 
 /* Process one pair of files, already opened.  */
-- 
2.5.0

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]