From e3d39609d16dccfef8fd1f02090fcd1df82736df Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Wed, 25 Jul 2018 10:56:45 +0100 Subject: [PATCH] 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. --- 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 f8774850968..b40b267829c 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,21 @@ +2018-07-25 Nick Clifton + + * 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 * po/sv.po: Updated Swedish translation. diff --git a/binutils/rdcoff.c b/binutils/rdcoff.c index cc6fec51175..2f0c316e0e0 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 4a690f62822..2a238737bb7 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 7c5a0266bdd..fe8560cf79a 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, §ion, & 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) { -- 2.30.2