readelf: segfaults fuzzing multiple object files

This patch is aimed at fixing a number of oss-fuzz segfaults that
don't reproduce reliably with their current infrastructure, the
problem being that one invocation of readelf is effectively being run
on multiple object files.  I believe that these segfaults could be
reliably reproduced with just two fuzzed objects being presented to
readelf, but those inputs are currently not identified by oss-fuzz.
So there is some guesswork involved in this patch.  The idea here is
to clear stashed data such as symtab_shndx_list that is processed
using section header info, at the same time that header info is
cleared.

	* readelf.c (process_section_headers): Free dynamic symbols etc.
	earlier.
This commit is contained in:
Alan Modra 2020-04-20 09:54:46 +09:30
parent 58ee9a8a46
commit 8ff66993e0
2 changed files with 19 additions and 15 deletions

View file

@ -1,3 +1,8 @@
2020-04-20 Alan Modra <amodra@gmail.com>
* readelf.c (process_section_headers): Free dynamic symbols etc.
earlier.
2020-04-20 Alan Modra <amodra@gmail.com>
* readelf.c (get_num_dynamic_syms): Formatting. Don't return

View file

@ -6132,6 +6132,20 @@ process_section_headers (Filedata * filedata)
free (filedata->section_headers);
filedata->section_headers = NULL;
free (dynamic_symbols);
dynamic_symbols = NULL;
num_dynamic_syms = 0;
free (dynamic_strings);
dynamic_strings = NULL;
dynamic_strings_length = 0;
free (dynamic_syminfo);
dynamic_syminfo = NULL;
while (symtab_shndx_list != NULL)
{
elf_section_list *next = symtab_shndx_list->next;
free (symtab_shndx_list);
symtab_shndx_list = next;
}
if (filedata->file_header.e_shnum == 0)
{
@ -6186,21 +6200,6 @@ process_section_headers (Filedata * filedata)
/* Scan the sections for the dynamic symbol table
and dynamic string table and debug sections. */
free (dynamic_symbols);
dynamic_symbols = NULL;
num_dynamic_syms = 0;
free (dynamic_strings);
dynamic_strings = NULL;
dynamic_strings_length = 0;
free (dynamic_syminfo);
dynamic_syminfo = NULL;
while (symtab_shndx_list != NULL)
{
elf_section_list *next = symtab_shndx_list->next;
free (symtab_shndx_list);
symtab_shndx_list = next;
}
eh_addr_size = is_32bit_elf ? 4 : 8;
switch (filedata->file_header.e_machine)
{