From 8ff66993e0b57b20067d7a1b6c72a72f4cada2cf Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 20 Apr 2020 09:54:46 +0930 Subject: [PATCH] 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. --- binutils/ChangeLog | 5 +++++ binutils/readelf.c | 29 ++++++++++++++--------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 92d9b298ee7..86eb5781400 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2020-04-20 Alan Modra + + * readelf.c (process_section_headers): Free dynamic symbols etc. + earlier. + 2020-04-20 Alan Modra * readelf.c (get_num_dynamic_syms): Formatting. Don't return diff --git a/binutils/readelf.c b/binutils/readelf.c index 601e329fdcf..d9c9b7ea0c1 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) { -- 2.30.2