dwarf-reader: handle symtab.section_header.sh_entsize == 0
authorMatthias Maennich <maennich@google.com>
Fri, 24 Jan 2020 22:45:56 +0000 (22:45 +0000)
committerMatthias Maennich <maennich@google.com>
Fri, 24 Jan 2020 22:53:30 +0000 (22:53 +0000)
A broken elf file with a sh_entsize of 0 makes the dwarf reader crash
due to a division by zero. Fix this by validating the input and exiting
early in that case.

* src/abg-dwarf-reader.cc (load_symbol_maps_from_symtab_section):
Handle elf file with invalid sh_entsize.
* tests/test-read-dwarf.cc (test_task::perform): handle empty
in_abi_path and out_abi_path as 'read only' test.
(InOutSpec): add test case.
* tests/data/test-read-dwarf/test25-bogus-binary.elf: new test data.

Signed-off-by: Matthias Maennich <maennich@google.com>
src/abg-dwarf-reader.cc
tests/data/test-read-dwarf/test25-bogus-binary.elf [new file with mode: 0644]
tests/test-read-dwarf.cc

index d3efb02..555170e 100644 (file)
@@ -7388,6 +7388,11 @@ public:
     GElf_Shdr header_mem;
     GElf_Shdr* symtab_sheader = gelf_getshdr(symtab_section,
                                             &header_mem);
+
+    // check for bogus section header
+    if (symtab_sheader->sh_entsize == 0)
+      return false;
+
     size_t nb_syms = symtab_sheader->sh_size / symtab_sheader->sh_entsize;
 
     Elf_Data* symtab = elf_getdata(symtab_section, 0);
diff --git a/tests/data/test-read-dwarf/test25-bogus-binary.elf b/tests/data/test-read-dwarf/test25-bogus-binary.elf
new file mode 100644 (file)
index 0000000..b00a969
Binary files /dev/null and b/tests/data/test-read-dwarf/test25-bogus-binary.elf differ
index 7c65696..8f460fe 100644 (file)
@@ -253,6 +253,12 @@ InOutSpec in_out_specs[] =
     "output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi",
   },
 #endif
+  {
+    "data/test-read-dwarf/test25-bogus-binary.elf",
+    "",
+    "",
+    "",
+  },
   // This should be the last entry.
   {NULL, NULL, NULL, NULL}
 };
@@ -324,6 +330,12 @@ struct test_task : public abigail::workers::task
       set_suppressions(*ctxt, in_suppr_spec_path);
 
     abigail::corpus_sptr corp = read_corpus_from_elf(*ctxt, status);
+    // if there is no output and no input, assume that we do not care about the
+    // actual read result, just that it succeeded.
+    if (in_abi_path.empty() && out_abi_path.empty()) {
+       // Phew! we made it here and we did not crash! yay!
+       return;
+    }
     if (!corp)
       {
        error_message = string("failed to read ") + in_elf_path  + "\n";