diff options
author | Alan Modra <amodra@gmail.com> | 2020-04-20 09:54:46 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2020-04-20 11:09:43 +0930 |
commit | 8ff66993e0b57b20067d7a1b6c72a72f4cada2cf (patch) | |
tree | 5009a15d97f28daa49f1eabc21645167c7308531 /binutils | |
parent | 58ee9a8a46b632ada94ae057acc23ba3928afa66 (diff) | |
download | gdb-8ff66993e0b57b20067d7a1b6c72a72f4cada2cf.zip gdb-8ff66993e0b57b20067d7a1b6c72a72f4cada2cf.tar.gz gdb-8ff66993e0b57b20067d7a1b6c72a72f4cada2cf.tar.bz2 |
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.
Diffstat (limited to 'binutils')
-rw-r--r-- | binutils/ChangeLog | 5 | ||||
-rw-r--r-- | binutils/readelf.c | 29 |
2 files changed, 19 insertions, 15 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 92d9b29..86eb578 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,5 +1,10 @@ 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 on error without freeing. (process_dynamic_section): Don't recreate dynamic symbols from diff --git a/binutils/readelf.c b/binutils/readelf.c index 601e329..d9c9b7e 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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) { |