mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-26 22:07:58 +08:00
readelf section reading
This is a followup to git commit 8ff66993e0b5, a patch aimed at segfaults found invoking readelf multiple times with fuzzed objects. In that patch I added code to clear more stashed data early in process_section_headers, along with any stashed section headers. This patch instead relies on clearing out the stash at the end of process_object, making sure that process_object doesn't exit early. The patch also introduces some new wrapper functions. * readelf.c (GET_ELF_SYMBOLS): Delete. Replace with.. (get_elf_symbols): ..this new function throughout. (get_32bit_section_headers): Don't free section_headers. (get_64bit_section_headers): Likewise. (get_section_headers): New function, use throughout in place of 32bit and 64bit variants. (get_dynamic_section): Similarly. (process_section_headers): Don't free filedata memory here. (get_file_header): Don't get section headers here.. (process_object): ..Read them here instead. Don't exit without freeing filedata memory.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
2021-06-11 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* readelf.c (GET_ELF_SYMBOLS): Delete. Replace with..
|
||||||
|
(get_elf_symbols): ..this new function throughout.
|
||||||
|
(get_32bit_section_headers): Don't free section_headers.
|
||||||
|
(get_64bit_section_headers): Likewise.
|
||||||
|
(get_section_headers): New function, use throughout in place of
|
||||||
|
32bit and 64bit variants.
|
||||||
|
(get_dynamic_section): Similarly.
|
||||||
|
(process_section_headers): Don't free filedata memory here.
|
||||||
|
(get_file_header): Don't get section headers here..
|
||||||
|
(process_object): ..Read them here instead. Don't exit without
|
||||||
|
freeing filedata memory.
|
||||||
|
|
||||||
2021-06-09 Nick Clifton <nickc@redhat.com>
|
2021-06-09 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* MAINTAINERS: Remove Daniel Jacobwitz from the maintainers list.
|
* MAINTAINERS: Remove Daniel Jacobwitz from the maintainers list.
|
||||||
|
@ -357,10 +357,6 @@ static const char * get_symbol_version_string
|
|||||||
|
|
||||||
#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
|
#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
|
||||||
|
|
||||||
#define GET_ELF_SYMBOLS(file, section, sym_count) \
|
|
||||||
(is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
|
|
||||||
: get_64bit_elf_symbols (file, section, sym_count))
|
|
||||||
|
|
||||||
#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
|
#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
|
||||||
(strtab != NULL && offset < strtab_size)
|
(strtab != NULL && offset < strtab_size)
|
||||||
#define VALID_DYNAMIC_NAME(filedata, offset) \
|
#define VALID_DYNAMIC_NAME(filedata, offset) \
|
||||||
@ -5756,7 +5752,6 @@ get_32bit_section_headers (Filedata * filedata, bool probe)
|
|||||||
if (shdrs == NULL)
|
if (shdrs == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
free (filedata->section_headers);
|
|
||||||
filedata->section_headers = (Elf_Internal_Shdr *)
|
filedata->section_headers = (Elf_Internal_Shdr *)
|
||||||
cmalloc (num, sizeof (Elf_Internal_Shdr));
|
cmalloc (num, sizeof (Elf_Internal_Shdr));
|
||||||
if (filedata->section_headers == NULL)
|
if (filedata->section_headers == NULL)
|
||||||
@ -5823,7 +5818,6 @@ get_64bit_section_headers (Filedata * filedata, bool probe)
|
|||||||
if (shdrs == NULL)
|
if (shdrs == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
free (filedata->section_headers);
|
|
||||||
filedata->section_headers = (Elf_Internal_Shdr *)
|
filedata->section_headers = (Elf_Internal_Shdr *)
|
||||||
cmalloc (num, sizeof (Elf_Internal_Shdr));
|
cmalloc (num, sizeof (Elf_Internal_Shdr));
|
||||||
if (filedata->section_headers == NULL)
|
if (filedata->section_headers == NULL)
|
||||||
@ -5858,6 +5852,21 @@ get_64bit_section_headers (Filedata * filedata, bool probe)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
get_section_headers (Filedata *filedata, bool probe)
|
||||||
|
{
|
||||||
|
if (filedata->section_headers != NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (filedata->file_header.e_shoff == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (is_32bit_elf)
|
||||||
|
return get_32bit_section_headers (filedata, probe);
|
||||||
|
else
|
||||||
|
return get_64bit_section_headers (filedata, probe);
|
||||||
|
}
|
||||||
|
|
||||||
static Elf_Internal_Sym *
|
static Elf_Internal_Sym *
|
||||||
get_32bit_elf_symbols (Filedata * filedata,
|
get_32bit_elf_symbols (Filedata * filedata,
|
||||||
Elf_Internal_Shdr * section,
|
Elf_Internal_Shdr * section,
|
||||||
@ -6094,6 +6103,17 @@ get_64bit_elf_symbols (Filedata * filedata,
|
|||||||
return isyms;
|
return isyms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Elf_Internal_Sym *
|
||||||
|
get_elf_symbols (Filedata *filedata,
|
||||||
|
Elf_Internal_Shdr *section,
|
||||||
|
unsigned long *num_syms_return)
|
||||||
|
{
|
||||||
|
if (is_32bit_elf)
|
||||||
|
return get_32bit_elf_symbols (filedata, section, num_syms_return);
|
||||||
|
else
|
||||||
|
return get_64bit_elf_symbols (filedata, section, num_syms_return);
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
|
get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
|
||||||
{
|
{
|
||||||
@ -6451,23 +6471,6 @@ process_section_headers (Filedata * filedata)
|
|||||||
Elf_Internal_Shdr * section;
|
Elf_Internal_Shdr * section;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
free (filedata->section_headers);
|
|
||||||
filedata->section_headers = NULL;
|
|
||||||
free (filedata->dynamic_symbols);
|
|
||||||
filedata->dynamic_symbols = NULL;
|
|
||||||
filedata->num_dynamic_syms = 0;
|
|
||||||
free (filedata->dynamic_strings);
|
|
||||||
filedata->dynamic_strings = NULL;
|
|
||||||
filedata->dynamic_strings_length = 0;
|
|
||||||
free (filedata->dynamic_syminfo);
|
|
||||||
filedata->dynamic_syminfo = NULL;
|
|
||||||
while (filedata->symtab_shndx_list != NULL)
|
|
||||||
{
|
|
||||||
elf_section_list *next = filedata->symtab_shndx_list->next;
|
|
||||||
free (filedata->symtab_shndx_list);
|
|
||||||
filedata->symtab_shndx_list = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filedata->file_header.e_shnum == 0)
|
if (filedata->file_header.e_shnum == 0)
|
||||||
{
|
{
|
||||||
/* PR binutils/12467. */
|
/* PR binutils/12467. */
|
||||||
@ -6497,16 +6500,8 @@ process_section_headers (Filedata * filedata)
|
|||||||
(unsigned long) filedata->file_header.e_shoff);
|
(unsigned long) filedata->file_header.e_shoff);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_32bit_elf)
|
if (!get_section_headers (filedata, false))
|
||||||
{
|
return false;
|
||||||
if (! get_32bit_section_headers (filedata, false))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (! get_64bit_section_headers (filedata, false))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read in the string table, so that we have names to display. */
|
/* Read in the string table, so that we have names to display. */
|
||||||
if (filedata->file_header.e_shstrndx != SHN_UNDEF
|
if (filedata->file_header.e_shstrndx != SHN_UNDEF
|
||||||
@ -6615,7 +6610,7 @@ process_section_headers (Filedata * filedata)
|
|||||||
|
|
||||||
CHECK_ENTSIZE (section, i, Sym);
|
CHECK_ENTSIZE (section, i, Sym);
|
||||||
filedata->dynamic_symbols
|
filedata->dynamic_symbols
|
||||||
= GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
|
= get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
|
||||||
filedata->dynamic_symtab_section = section;
|
filedata->dynamic_symtab_section = section;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -7170,7 +7165,7 @@ get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
|
|||||||
{
|
{
|
||||||
*strtab = NULL;
|
*strtab = NULL;
|
||||||
*strtablen = 0;
|
*strtablen = 0;
|
||||||
*symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
|
*symtab = get_elf_symbols (filedata, symsec, nsyms);
|
||||||
|
|
||||||
if (*symtab == NULL)
|
if (*symtab == NULL)
|
||||||
return false;
|
return false;
|
||||||
@ -7341,7 +7336,7 @@ process_section_groups (Filedata * filedata)
|
|||||||
{
|
{
|
||||||
symtab_sec = sec;
|
symtab_sec = sec;
|
||||||
free (symtab);
|
free (symtab);
|
||||||
symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
|
symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symtab == NULL)
|
if (symtab == NULL)
|
||||||
@ -10278,6 +10273,18 @@ get_64bit_dynamic_section (Filedata * filedata)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
get_dynamic_section (Filedata *filedata)
|
||||||
|
{
|
||||||
|
if (filedata->dynamic_section)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (is_32bit_elf)
|
||||||
|
return get_32bit_dynamic_section (filedata);
|
||||||
|
else
|
||||||
|
return get_64bit_dynamic_section (filedata);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_dynamic_flags (bfd_vma flags)
|
print_dynamic_flags (bfd_vma flags)
|
||||||
{
|
{
|
||||||
@ -10621,16 +10628,8 @@ process_dynamic_section (Filedata * filedata)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_32bit_elf)
|
if (!get_dynamic_section (filedata))
|
||||||
{
|
return false;
|
||||||
if (! get_32bit_dynamic_section (filedata))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (! get_64bit_dynamic_section (filedata))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the appropriate symbol table. */
|
/* Find the appropriate symbol table. */
|
||||||
if (filedata->dynamic_symbols == NULL || do_histogram)
|
if (filedata->dynamic_symbols == NULL || do_histogram)
|
||||||
@ -10714,7 +10713,7 @@ the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
|
|||||||
|
|
||||||
section.sh_name = filedata->string_table_length;
|
section.sh_name = filedata->string_table_length;
|
||||||
filedata->dynamic_symbols
|
filedata->dynamic_symbols
|
||||||
= GET_ELF_SYMBOLS (filedata, §ion,
|
= get_elf_symbols (filedata, §ion,
|
||||||
&filedata->num_dynamic_syms);
|
&filedata->num_dynamic_syms);
|
||||||
if (filedata->dynamic_symbols == NULL
|
if (filedata->dynamic_symbols == NULL
|
||||||
|| filedata->num_dynamic_syms != num_of_syms)
|
|| filedata->num_dynamic_syms != num_of_syms)
|
||||||
@ -11744,7 +11743,7 @@ process_version_sections (Filedata * filedata)
|
|||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
|
|
||||||
symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
|
symbols = get_elf_symbols (filedata, link_section, & num_syms);
|
||||||
if (symbols == NULL)
|
if (symbols == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -12946,7 +12945,7 @@ process_symbol_table (Filedata * filedata)
|
|||||||
else
|
else
|
||||||
printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
|
printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
|
||||||
|
|
||||||
symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
|
symtab = get_elf_symbols (filedata, section, & num_syms);
|
||||||
if (symtab == NULL)
|
if (symtab == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -14312,7 +14311,7 @@ apply_relocations (Filedata * filedata,
|
|||||||
if (filedata->file_header.e_machine == EM_SH)
|
if (filedata->file_header.e_machine == EM_SH)
|
||||||
is_rela = false;
|
is_rela = false;
|
||||||
|
|
||||||
symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
|
symtab = get_elf_symbols (filedata, symsec, & num_syms);
|
||||||
|
|
||||||
for (rp = relocs; rp < relocs + num_relocs; ++rp)
|
for (rp = relocs; rp < relocs + num_relocs; ++rp)
|
||||||
{
|
{
|
||||||
@ -21185,16 +21184,6 @@ get_file_header (Filedata * filedata)
|
|||||||
filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
|
filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filedata->file_header.e_shoff)
|
|
||||||
{
|
|
||||||
/* There may be some extensions in the first section header. Don't
|
|
||||||
bomb if we can't read it. */
|
|
||||||
if (is_32bit_elf)
|
|
||||||
get_32bit_section_headers (filedata, true);
|
|
||||||
else
|
|
||||||
get_64bit_section_headers (filedata, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21305,19 +21294,8 @@ open_file (const char * pathname, bool is_separate)
|
|||||||
if (! get_file_header (filedata))
|
if (! get_file_header (filedata))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (filedata->file_header.e_shoff)
|
if (!get_section_headers (filedata, false))
|
||||||
{
|
goto fail;
|
||||||
bool res;
|
|
||||||
|
|
||||||
/* Read the section headers again, this time for real. */
|
|
||||||
if (is_32bit_elf)
|
|
||||||
res = get_32bit_section_headers (filedata, false);
|
|
||||||
else
|
|
||||||
res = get_64bit_section_headers (filedata, false);
|
|
||||||
|
|
||||||
if (!res)
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filedata;
|
return filedata;
|
||||||
|
|
||||||
@ -21393,8 +21371,15 @@ process_object (Filedata * filedata)
|
|||||||
|
|
||||||
initialise_dump_sects (filedata);
|
initialise_dump_sects (filedata);
|
||||||
|
|
||||||
|
/* There may be some extensions in the first section header. Don't
|
||||||
|
bomb if we can't read it. */
|
||||||
|
get_section_headers (filedata, true);
|
||||||
|
|
||||||
if (! process_file_header (filedata))
|
if (! process_file_header (filedata))
|
||||||
return false;
|
{
|
||||||
|
res = false;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (! process_section_headers (filedata))
|
if (! process_section_headers (filedata))
|
||||||
{
|
{
|
||||||
@ -21490,6 +21475,7 @@ process_object (Filedata * filedata)
|
|||||||
if (! process_arch_specific (filedata))
|
if (! process_arch_specific (filedata))
|
||||||
res = false;
|
res = false;
|
||||||
|
|
||||||
|
out:
|
||||||
free_filedata (filedata);
|
free_filedata (filedata);
|
||||||
|
|
||||||
free_debug_memory ();
|
free_debug_memory ();
|
||||||
|
Reference in New Issue
Block a user