fix some elf linker memory leaks

Alan Modra amodra@bigpond.net.au
Fri Aug 8 08:00:00 GMT 2008


	* elf.c (bfd_elf_get_elf_syms): Don't leak memory on error.
	* elflink.c (_bfd_elf_link_read_relocs): bfd_release on error.
	(elf_link_add_object_symbols): Don't leak memory on error.
	(bfd_elf_size_dynsym_hash_dynstr): Likewise.
	(elf_fixup_link_order): Free sections.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.461
diff -u -p -r1.461 elf.c
--- bfd/elf.c	7 Aug 2008 20:04:32 -0000	1.461
+++ bfd/elf.c	8 Aug 2008 07:29:01 -0000
@@ -358,6 +358,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   const bfd_byte *esym;
   Elf_External_Sym_Shndx *alloc_extshndx;
   Elf_External_Sym_Shndx *shndx;
+  Elf_Internal_Sym *alloc_intsym;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
   const struct elf_backend_data *bed;
@@ -379,6 +380,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   /* Read the symbols.  */
   alloc_ext = NULL;
   alloc_extshndx = NULL;
+  alloc_intsym = NULL;
   bed = get_elf_backend_data (ibfd);
   extsym_size = bed->s->sizeof_sym;
   amt = symcount * extsym_size;
@@ -419,7 +421,8 @@ bfd_elf_get_elf_syms (bfd *ibfd,
 
   if (intsym_buf == NULL)
     {
-      intsym_buf = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
+      alloc_intsym = bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
+      intsym_buf = alloc_intsym;
       if (intsym_buf == NULL)
 	goto out;
     }
@@ -435,6 +438,8 @@ bfd_elf_get_elf_syms (bfd *ibfd,
 	(*_bfd_error_handler) (_("%B symbol number %lu references "
 				 "nonexistent SHT_SYMTAB_SHNDX section"),
 			       ibfd, (unsigned long) symoffset);
+	if (alloc_intsym != NULL)
+	  free (alloc_intsym);
 	intsym_buf = NULL;
 	goto out;
       }
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.307
diff -u -p -r1.307 elflink.c
--- bfd/elflink.c	7 Aug 2008 20:04:32 -0000	1.307
+++ bfd/elflink.c	8 Aug 2008 07:29:09 -0000
@@ -2178,7 +2178,7 @@ _bfd_elf_link_read_relocs (bfd *abfd,
       size = o->reloc_count;
       size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela);
       if (keep_memory)
-	internal_relocs = bfd_alloc (abfd, size);
+	internal_relocs = alloc2 = bfd_alloc (abfd, size);
       else
 	internal_relocs = alloc2 = bfd_malloc (size);
       if (internal_relocs == NULL)
@@ -2226,7 +2226,12 @@ _bfd_elf_link_read_relocs (bfd *abfd,
   if (alloc1 != NULL)
     free (alloc1);
   if (alloc2 != NULL)
-    free (alloc2);
+    {
+      if (keep_memory)
+	bfd_release (abfd, alloc2);
+      else
+	free (alloc2);
+    }
   return NULL;
 }
 
@@ -4626,7 +4631,11 @@ elf_link_add_object_symbols (bfd *abfd, 
 		  if (hlook->dynindx != -1 && h->dynindx == -1)
 		    {
 		      if (! bfd_elf_link_record_dynamic_symbol (info, h))
-			goto error_return;
+			{
+			err_free_sym_hash:
+			  free (sorted_sym_hash);
+			  goto error_return;
+			}
 		    }
 
 		  /* If the real definition is in the list of dynamic
@@ -4637,7 +4646,7 @@ elf_link_add_object_symbols (bfd *abfd, 
 		  if (h->dynindx != -1 && hlook->dynindx == -1)
 		    {
 		      if (! bfd_elf_link_record_dynamic_symbol (info, hlook))
-			goto error_return;
+			goto err_free_sym_hash;
 		    }
 		  break;
 		}
@@ -6249,7 +6258,10 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *ou
 	  elf_link_hash_traverse (elf_hash_table (info),
 				  elf_collect_hash_codes, &hashinf);
 	  if (hashinf.error)
-	    return FALSE;
+	    {
+	      free (hashcodes);
+	      return FALSE;
+	    }
 
 	  nsyms = hashinf.hashcodes - hashcodes;
 	  bucketcount
@@ -6301,7 +6313,10 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *ou
 	  elf_link_hash_traverse (elf_hash_table (info),
 				  elf_collect_gnu_hash_codes, &cinfo);
 	  if (cinfo.error)
-	    return FALSE;
+	    {
+	      free (cinfo.hashcodes);
+	      return FALSE;
+	    }
 
 	  bucketcount
 	    = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1);
@@ -9847,6 +9862,7 @@ elf_fixup_link_order (bfd *abfd, asectio
       offset += sections[n]->size;
     }
 
+  free (sections);
   return TRUE;
 }
 

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list