[binutils-gdb] Fix potential memory leaks in some of the binutils source files.

Nick Clifton nickc@sourceware.org
Wed Jul 25 09:57:00 GMT 2018


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

commit e3d39609d16dccfef8fd1f02090fcd1df82736df
Author: Nick Clifton <nickc@redhat.com>
Date:   Wed Jul 25 10:56:45 2018 +0100

    Fix potential memory leaks in some of the binutils source files.
    
    	* rdcoff.c (parse_coff_struct_type): Free fields array upon early
    	exit.
    	(parse_coff_enum_type): Free names and vals arrays upon early
    	exit.
    	* rddbg.c (read_section_stabs_debugging_info): Free shandle and
    	strings and stabs arrays upon early exit.
    	* readelf.c (get_32bit_section_headers): Free shdrs structure upon
    	early exit.
    	(get_64bit_section_headers): Likewise.
    	(get_32bit_elf_symbols): Generate an error if multiple symbol
    	table index sections are associated with the same symbol section.
    	(get_64bit_elf_symbols): Likewise.
    	(process_dynamic_section): Generate an error if there are multiple
    	dynamic symbol table sections, multiple dynamic string tables or
    	multiple dynamic symbol information sections.

Diff:
---
 binutils/ChangeLog |  18 +++++++
 binutils/rdcoff.c  |   4 ++
 binutils/rddbg.c   |  24 +++++++---
 binutils/readelf.c | 135 +++++++++++++++++++++++++++++++----------------------
 4 files changed, 120 insertions(+), 61 deletions(-)

diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index f877485..b40b267 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,21 @@
+2018-07-25  Nick Clifton  <nickc@redhat.com>
+
+	* rdcoff.c (parse_coff_struct_type): Free fields array upon early
+	exit.
+	(parse_coff_enum_type): Free names and vals arrays upon early
+	exit.
+	* rddbg.c (read_section_stabs_debugging_info): Free shandle and
+	strings and stabs arrays upon early exit.
+	* readelf.c (get_32bit_section_headers): Free shdrs structure upon
+	early exit.
+	(get_64bit_section_headers): Likewise.
+	(get_32bit_elf_symbols): Generate an error if multiple symbol
+	table index sections are associated with the same symbol section.
+	(get_64bit_elf_symbols): Likewise.
+	(process_dynamic_section): Generate an error if there are multiple
+	dynamic symbol table sections, multiple dynamic string tables or
+	multiple dynamic symbol information sections.
+
 2018-07-24  Nick Clifton  <nickc@redhat.com>
 
 	* po/sv.po: Updated Swedish translation.
diff --git a/binutils/rdcoff.c b/binutils/rdcoff.c
index cc6fec5..2f0c316 100644
--- a/binutils/rdcoff.c
+++ b/binutils/rdcoff.c
@@ -409,6 +409,7 @@ parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
 	{
 	  non_fatal (_("bfd_coff_get_syment failed: %s"),
 		     bfd_errmsg (bfd_get_error ()));
+	  free (fields);
 	  return DEBUG_TYPE_NULL;
 	}
 
@@ -425,6 +426,7 @@ parse_coff_struct_type (bfd *abfd, struct coff_symbols *symbols,
 	    {
 	      non_fatal (_("bfd_coff_get_auxent failed: %s"),
 			 bfd_errmsg (bfd_get_error ()));
+	      free (fields);
 	      return DEBUG_TYPE_NULL;
 	    }
 	  psubaux = &auxent;
@@ -514,6 +516,8 @@ parse_coff_enum_type (bfd *abfd, struct coff_symbols *symbols,
 	{
 	  non_fatal (_("bfd_coff_get_syment failed: %s"),
 		     bfd_errmsg (bfd_get_error ()));
+	  free (names);
+	  free (vals);
 	  return DEBUG_TYPE_NULL;
 	}
 
diff --git a/binutils/rddbg.c b/binutils/rddbg.c
index 4a690f6..2a23873 100644
--- a/binutils/rddbg.c
+++ b/binutils/rddbg.c
@@ -128,6 +128,8 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
 	      fprintf (stderr, "%s: %s: %s\n",
 		       bfd_get_filename (abfd), names[i].secname,
 		       bfd_errmsg (bfd_get_error ()));
+	      free (shandle);
+	      free (stabs);
 	      return FALSE;
 	    }
 
@@ -138,6 +140,9 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
 	      fprintf (stderr, "%s: %s: %s\n",
 		       bfd_get_filename (abfd), names[i].strsecname,
 		       bfd_errmsg (bfd_get_error ()));
+	      free (shandle);
+	      free (strings);
+	      free (stabs);
 	      return FALSE;
 	    }
 	  /* Zero terminate the strings table, just in case.  */
@@ -146,7 +151,11 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
 	    {
 	      shandle = start_stab (dhandle, abfd, TRUE, syms, symcount);
 	      if (shandle == NULL)
-		return FALSE;
+		{
+		  free (strings);
+		  free (stabs);
+		  return FALSE;
+		}
 	    }
 
 	  *pfound = TRUE;
@@ -213,17 +222,16 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
 				   (long) (stab - stabs) / 12);
 			  break;
 			}
-		      else
-			s = concat (s, (char *) strings + strx,
-				    (const char *) NULL);
+
+		      s = concat (s, (char *) strings + strx,
+				  (const char *) NULL);
 
 		      /* We have to restore the backslash, because, if
 			 the linker is hashing stabs strings, we may
 			 see the same string more than once.  */
 		      *p = '\\';
 
-		      if (f != NULL)
-			free (f);
+		      free (f);
 		      f = s;
 		    }
 
@@ -233,6 +241,10 @@ read_section_stabs_debugging_info (bfd *abfd, asymbol **syms, long symcount,
 		    {
 		      stab_context ();
 		      free_saved_stabs ();
+		      free (f);
+		      free (shandle);
+		      free (stabs);
+		      free (strings);
 		      return FALSE;
 		    }
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 7c5a026..fe8560c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -5330,6 +5330,7 @@ get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
     {
       if (!probe)
 	error (_("Out of memory reading %u section headers\n"), num);
+      free (shdrs);
       return FALSE;
     }
 
@@ -5396,6 +5397,7 @@ get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
     {
       if (! probe)
 	error (_("Out of memory reading %u section headers\n"), num);
+      free (shdrs);
       return FALSE;
     }
 
@@ -5434,6 +5436,7 @@ get_32bit_elf_symbols (Filedata *           filedata,
   Elf_Internal_Sym * isyms = NULL;
   Elf_Internal_Sym * psym;
   unsigned int j;
+  elf_section_list * entry;
 
   if (section->sh_size == 0)
     {
@@ -5475,30 +5478,35 @@ get_32bit_elf_symbols (Filedata *           filedata,
   if (esyms == NULL)
     goto exit_point;
 
-  {
-    elf_section_list * entry;
-
-    shndx = NULL;
-    for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
-      if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
-	{
-	  shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
-						       entry->hdr->sh_offset,
-						       1, entry->hdr->sh_size,
-						       _("symbol table section indices"));
-	  if (shndx == NULL)
-	    goto exit_point;
-	  /* PR17531: file: heap-buffer-overflow */
-	  else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
-	    {
-	      error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
-		     printable_section_name (filedata, entry->hdr),
-		     (unsigned long) entry->hdr->sh_size,
-		     (unsigned long) section->sh_size);
-	      goto exit_point;
-	    }
+  shndx = NULL;
+  for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
+    {
+      if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
+	continue;
+
+      if (shndx != NULL)
+	{
+	  error (_("Multiple symbol table index sections associated with the same symbol section\n"));
+	  free (shndx);
+	}
+
+      shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
+						   entry->hdr->sh_offset,
+						   1, entry->hdr->sh_size,
+						   _("symbol table section indices"));
+      if (shndx == NULL)
+	goto exit_point;
+
+      /* PR17531: file: heap-buffer-overflow */
+      if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
+	{
+	  error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
+		 printable_section_name (filedata, entry->hdr),
+		 (unsigned long) entry->hdr->sh_size,
+		 (unsigned long) section->sh_size);
+	  goto exit_point;
 	}
-  }
+    }
 
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
@@ -5525,10 +5533,8 @@ get_32bit_elf_symbols (Filedata *           filedata,
     }
 
  exit_point:
-  if (shndx != NULL)
-    free (shndx);
-  if (esyms != NULL)
-    free (esyms);
+  free (shndx);
+  free (esyms);
 
   if (num_syms_return != NULL)
     * num_syms_return = isyms == NULL ? 0 : number;
@@ -5547,6 +5553,7 @@ get_64bit_elf_symbols (Filedata *           filedata,
   Elf_Internal_Sym * isyms = NULL;
   Elf_Internal_Sym * psym;
   unsigned int j;
+  elf_section_list * entry;
 
   if (section->sh_size == 0)
     {
@@ -5588,30 +5595,35 @@ get_64bit_elf_symbols (Filedata *           filedata,
   if (!esyms)
     goto exit_point;
 
-  {
-    elf_section_list * entry;
-
-    shndx = NULL;
-    for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
-      if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
-	{
-	  shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
-						       entry->hdr->sh_offset,
-						       1, entry->hdr->sh_size,
-						       _("symbol table section indices"));
-	  if (shndx == NULL)
-	    goto exit_point;
-	  /* PR17531: file: heap-buffer-overflow */
-	  else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
-	    {
-	      error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
-		     printable_section_name (filedata, entry->hdr),
-		     (unsigned long) entry->hdr->sh_size,
-		     (unsigned long) section->sh_size);
-	      goto exit_point;
-	    }
+  shndx = NULL;
+  for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
+    {
+      if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
+	continue;
+
+      if (shndx != NULL)
+	{
+	  error (_("Multiple symbol table index sections associated with the same symbol section\n"));
+	  free (shndx);
 	}
-  }
+
+      shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
+						   entry->hdr->sh_offset,
+						   1, entry->hdr->sh_size,
+						   _("symbol table section indices"));
+      if (shndx == NULL)
+	goto exit_point;
+
+      /* PR17531: file: heap-buffer-overflow */
+      if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
+	{
+	  error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
+		 printable_section_name (filedata, entry->hdr),
+		 (unsigned long) entry->hdr->sh_size,
+		 (unsigned long) section->sh_size);
+	  goto exit_point;
+	}
+    }
 
   isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
 
@@ -5640,10 +5652,8 @@ get_64bit_elf_symbols (Filedata *           filedata,
     }
 
  exit_point:
-  if (shndx != NULL)
-    free (shndx);
-  if (esyms != NULL)
-    free (esyms);
+  free (shndx);
+  free (esyms);
 
   if (num_syms_return != NULL)
     * num_syms_return = isyms == NULL ? 0 : number;
@@ -9672,6 +9682,11 @@ process_dynamic_section (Filedata * filedata)
 	    section.sh_entsize = sizeof (Elf64_External_Sym);
 	  section.sh_name = filedata->string_table_length;
 
+	  if (dynamic_symbols != NULL)
+	    {
+	      error (_("Multiple dynamic symbol table sections found\n"));
+	      free (dynamic_symbols);
+	    }
 	  dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
 	  if (num_dynamic_syms < 1)
 	    {
@@ -9715,11 +9730,16 @@ process_dynamic_section (Filedata * filedata)
 	      continue;
 	    }
 
+	  if (dynamic_strings != NULL)
+	    {
+	      error (_("Multiple dynamic string tables found\n"));
+	      free (dynamic_strings);
+	    }
+
 	  dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
                                                str_tab_len,
                                                _("dynamic string table"));
 	  dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
-	  break;
 	}
     }
 
@@ -9762,6 +9782,11 @@ process_dynamic_section (Filedata * filedata)
 	  if (!extsyminfo)
 	    return FALSE;
 
+	  if (dynamic_syminfo != NULL)
+	    {
+	      error (_("Multiple dynamic symbol information sections found\n"));
+	      free (dynamic_syminfo);
+	    }
 	  dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
 	  if (dynamic_syminfo == NULL)
 	    {



More information about the Binutils-cvs mailing list