aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2018-07-25 10:56:45 +0100
committerNick Clifton <nickc@redhat.com>2018-07-25 10:56:45 +0100
commite3d39609d16dccfef8fd1f02090fcd1df82736df (patch)
tree1399c03846e9db283a88eabedf40a28ef397c802
parent491993044ba6cfb2b0fc93c8b3032d5c91cccda5 (diff)
downloadgdb-e3d39609d16dccfef8fd1f02090fcd1df82736df.zip
gdb-e3d39609d16dccfef8fd1f02090fcd1df82736df.tar.gz
gdb-e3d39609d16dccfef8fd1f02090fcd1df82736df.tar.bz2
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.
-rw-r--r--binutils/ChangeLog18
-rw-r--r--binutils/rdcoff.c4
-rw-r--r--binutils/rddbg.c24
-rw-r--r--binutils/readelf.c135
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)
{