[binutils-gdb] readelf: segfaults fuzzing multiple object files

Alan Modra amodra@sourceware.org
Mon Apr 20 01:40:12 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8ff66993e0b57b20067d7a1b6c72a72f4cada2cf

commit 8ff66993e0b57b20067d7a1b6c72a72f4cada2cf
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Apr 20 09:54:46 2020 +0930

    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.

Diff:
---
 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  <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
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)
     {


More information about the Binutils-cvs mailing list