From a3f1b7ca4423621f540a2581289ce57cb4bf3f72 Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Sat, 7 Mar 2020 20:39:13 +0700 Subject: [PATCH] Add resilience for degenerate cases present in files with only debug information (#287) Some ELF files which contain only debug symbols have important sections present in the section table but marked as NOBITS instead of PROGBITS. Attempting to extract the segments can lead to crashes through parsing invalid data. The first patch modifies the dynamic segment/section specifically to add a flag for this case, since it seems to assume that there will always be at least one entry, DT_NULL. The second patch modifies the segment code more generally to return a dummy answer for what data it holds. The actual way that this change prevents a crash is while trying to parse .eh_frame when it is in fact NOBITS - originally I had a more targeted patch, but decided that it was important enough to do more generally --- elftools/elf/dynamic.py | 24 +++++++-- elftools/elf/sections.py | 8 ++- elftools/elf/structs.py | 45 ++++++++++------ test/test_dbgfile.py | 54 ++++++++++++++++++++ test/testfiles_for_unittests/debug_info.elf | Bin 0 -> 29808 bytes 5 files changed, 109 insertions(+), 22 deletions(-) create mode 100644 test/test_dbgfile.py create mode 100644 test/testfiles_for_unittests/debug_info.elf diff --git a/elftools/elf/dynamic.py b/elftools/elf/dynamic.py index fcdec4e..5a7c99c 100644 --- a/elftools/elf/dynamic.py +++ b/elftools/elf/dynamic.py @@ -73,13 +73,22 @@ class DynamicTag(object): class Dynamic(object): """ Shared functionality between dynamic sections and segments. """ - def __init__(self, stream, elffile, stringtable, position): + def __init__(self, stream, elffile, stringtable, position, empty): + """ + :param stream: The file-like object from which to load data + :param elffile: The parent elffile object + :param stringtable: A stringtable reference to use for parsing string references in entries + :param position: The file offset of the dynamic segment/section + :param empty: Whether this is a degenerate case with zero entries. Normally, every dynamic table + will have at least one entry, the DT_NULL terminator. + """ self.elffile = elffile self.elfstructs = elffile.structs self._stream = stream - self._num_tags = -1 + self._num_tags = -1 if not empty else 0 self._offset = position self._tagsize = self.elfstructs.Elf_Dyn.sizeof() + self._empty = empty # Do not access this directly yourself; use _get_stringtable() instead. self._stringtable = stringtable @@ -125,6 +134,8 @@ class Dynamic(object): def _iter_tags(self, type=None): """ Yield all raw tags (limit to |type| if specified) """ + if self._empty: + return for n in itertools.count(): tag = self._get_tag(n) if type is None or tag['d_tag'] == type: @@ -141,6 +152,8 @@ class Dynamic(object): def _get_tag(self, n): """ Get the raw tag at index #n from the file """ + if self._num_tags != -1 and n >= self._num_tags: + raise IndexError(n) offset = self._offset + n * self._tagsize return struct_parse( self.elfstructs.Elf_Dyn, @@ -153,7 +166,7 @@ class Dynamic(object): return DynamicTag(self._get_tag(n), self._get_stringtable()) def num_tags(self): - """ Number of dynamic tags in the file + """ Number of dynamic tags in the file, including the DT_NULL tag """ if self._num_tags != -1: return self._num_tags @@ -207,7 +220,7 @@ class DynamicSection(Section, Dynamic): Section.__init__(self, header, name, elffile) stringtable = elffile.get_section(header['sh_link']) Dynamic.__init__(self, self.stream, self.elffile, stringtable, - self['sh_offset']) + self['sh_offset'], self['sh_type'] == 'SHT_NOBITS') class DynamicSegment(Segment, Dynamic): @@ -227,7 +240,8 @@ class DynamicSegment(Segment, Dynamic): stringtable = elffile.get_section(section['sh_link']) break Segment.__init__(self, header, stream) - Dynamic.__init__(self, stream, elffile, stringtable, self['p_offset']) + Dynamic.__init__(self, stream, elffile, stringtable, self['p_offset'], + self['p_filesz'] == 0) self._symbol_list = None self._symbol_name_map = None diff --git a/elftools/elf/sections.py b/elftools/elf/sections.py index 9d16b24..f60e3b3 100644 --- a/elftools/elf/sections.py +++ b/elftools/elf/sections.py @@ -74,6 +74,10 @@ class Section(object): Note that data is decompressed if the stored section data is compressed. """ + # If this section is NOBITS, there is no data. provide a dummy answer + if self.header['sh_type'] == 'SHT_NOBITS': + return b'\0'*self.data_size + # If this section is compressed, deflate it if self.compressed: c_type = self._compression_type @@ -137,7 +141,7 @@ class StringTableSection(Section): """ table_offset = self['sh_offset'] s = parse_cstring_from_stream(self.stream, table_offset + offset) - return s.decode('utf-8') if s else '' + return s.decode('utf-8', errors='replace') if s else '' class SymbolTableSection(Section): @@ -267,7 +271,7 @@ class StabSection(Section): while offset < end: stabs = struct_parse( self.structs.Elf_Stabs, - self.elffile.stream, + self.stream, stream_pos=offset) stabs['n_offset'] = offset offset += self.structs.Elf_Stabs.sizeof() diff --git a/elftools/elf/structs.py b/elftools/elf/structs.py index 789656d..67ff1f5 100644 --- a/elftools/elf/structs.py +++ b/elftools/elf/structs.py @@ -43,6 +43,17 @@ class ELFStructs(object): assert elfclass == 32 or elfclass == 64 self.little_endian = little_endian self.elfclass = elfclass + self.e_type = None + self.e_machine = None + self.e_ident_osabi = None + + def __getstate__(self): + return self.little_endian, self.elfclass, self.e_type, self.e_machine, self.e_ident_osabi + + def __setstate__(self, state): + self.little_endian, self.elfclass, e_type, e_machine, e_osabi = state + self.create_basic_structs() + self.create_advanced_structs(e_type, e_machine, e_osabi) def create_basic_structs(self): """ Create word-size related structs and ehdr struct needed for @@ -76,12 +87,16 @@ class ELFStructs(object): """ Create all ELF structs except the ehdr. They may possibly depend on provided e_type and/or e_machine parsed from ehdr. """ - self._create_phdr(e_machine) - self._create_shdr(e_machine) + self.e_type = e_type + self.e_machine = e_machine + self.e_ident_osabi = e_ident_osabi + + self._create_phdr() + self._create_shdr() self._create_chdr() self._create_sym() self._create_rel() - self._create_dyn(e_machine, e_ident_osabi) + self._create_dyn() self._create_sunw_syminfo() self._create_gnu_verneed() self._create_gnu_verdef() @@ -127,13 +142,13 @@ class ELFStructs(object): def _create_ntbs(self): self.Elf_ntbs = CString - def _create_phdr(self, e_machine=None): + def _create_phdr(self): p_type_dict = ENUM_P_TYPE_BASE - if e_machine == 'EM_ARM': + if self.e_machine == 'EM_ARM': p_type_dict = ENUM_P_TYPE_ARM - elif e_machine == 'EM_AARCH64': + elif self.e_machine == 'EM_AARCH64': p_type_dict = ENUM_P_TYPE_AARCH64 - elif e_machine == 'EM_MIPS': + elif self.e_machine == 'EM_MIPS': p_type_dict = ENUM_P_TYPE_MIPS if self.elfclass == 32: @@ -159,17 +174,17 @@ class ELFStructs(object): self.Elf_xword('p_align'), ) - def _create_shdr(self, e_machine=None): + def _create_shdr(self): """Section header parsing. Depends on e_machine because of machine-specific values in sh_type. """ sh_type_dict = ENUM_SH_TYPE_BASE - if e_machine == 'EM_ARM': + if self.e_machine == 'EM_ARM': sh_type_dict = ENUM_SH_TYPE_ARM - elif e_machine == 'EM_X86_64': + elif self.e_machine == 'EM_X86_64': sh_type_dict = ENUM_SH_TYPE_AMD64 - elif e_machine == 'EM_MIPS': + elif self.e_machine == 'EM_MIPS': sh_type_dict = ENUM_SH_TYPE_MIPS self.Elf_Shdr = Struct('Elf_Shdr', @@ -227,11 +242,11 @@ class ELFStructs(object): self.Elf_sxword('r_addend'), ) - def _create_dyn(self, e_machine=None, e_ident_osabi=None): + def _create_dyn(self): d_tag_dict = dict(ENUM_D_TAG_COMMON) - if e_machine in ENUMMAP_EXTRA_D_TAG_MACHINE: - d_tag_dict.update(ENUMMAP_EXTRA_D_TAG_MACHINE[e_machine]) - elif e_ident_osabi == 'ELFOSABI_SOLARIS': + if self.e_machine in ENUMMAP_EXTRA_D_TAG_MACHINE: + d_tag_dict.update(ENUMMAP_EXTRA_D_TAG_MACHINE[self.e_machine]) + elif self.e_ident_osabi == 'ELFOSABI_SOLARIS': d_tag_dict.update(ENUM_D_TAG_SOLARIS) self.Elf_Dyn = Struct('Elf_Dyn', diff --git a/test/test_dbgfile.py b/test/test_dbgfile.py new file mode 100644 index 0000000..bd5f06e --- /dev/null +++ b/test/test_dbgfile.py @@ -0,0 +1,54 @@ +""" +Test that elftools does not fail to load debug symbol ELF files +""" +import unittest +import os + +from elftools.elf.elffile import ELFFile, DynamicSection +from elftools.dwarf.callframe import ZERO + +class TestDBGFile(unittest.TestCase): + def test_dynamic_segment(self): + """ + Test that the degenerate case for the dynamic segment does not crash + """ + with open(os.path.join('test', 'testfiles_for_unittests', + 'debug_info.elf'), 'rb') as f: + elf = ELFFile(f) + + seen_dynamic_segment = False + for segment in elf.iter_segments(): + if segment.header.p_type != 'PT_DYNAMIC': + continue + + self.assertEqual(segment.num_tags(), 0, "The dynamic segment in this file should be empty") + seen_dynamic_segment = True + break + + self.assertTrue(seen_dynamic_segment, "There should be a dynamic segment in this file") + + def test_dynamic_section(self): + """ + Test that the degenerate case for the dynamic section does not crash + """ + with open(os.path.join('test', 'testfiles_for_unittests', + 'debug_info.elf'), 'rb') as f: + elf = ELFFile(f) + section = DynamicSection(elf.get_section_by_name('.dynamic').header, '.dynamic', elf) + + self.assertEqual(section.num_tags(), 0, "The dynamic section in this file should be empty") + + def test_eh_frame(self): + """ + Test that parsing .eh_frame with SHT_NOBITS does not crash + """ + with open(os.path.join('test', 'testfiles_for_unittests', + 'debug_info.elf'), 'rb') as f: + elf = ELFFile(f) + dwarf = elf.get_dwarf_info() + eh_frame = list(dwarf.EH_CFI_entries()) + self.assertEqual(len(eh_frame), 1, "There should only be the ZERO entry in eh_frame") + self.assertIs(type(eh_frame[0]), ZERO, "The only eh_frame entry should be the terminator") + +if __name__ == '__main__': + unittest.main() diff --git a/test/testfiles_for_unittests/debug_info.elf b/test/testfiles_for_unittests/debug_info.elf new file mode 100644 index 0000000000000000000000000000000000000000..502b92027f339ecac8a7fed02b5123a63ada9b01 GIT binary patch literal 29808 zcmZU)1FR@bum*T++qP}nwr!t#Y}>YN+x9)SZCiW)_x2^5Y$erI-QN^C>GaI>O!HqQnVT#9pO#XHMfApXIzqA3A{^9@M_&EQ3|HuE?{}=5)iSmzu|FO87D!{U%K~D&T zfO_$tcr-%}^$HIQyf$%RVJ-p+5mO^eLpuUCI%YZsS`NzpRS1|E7}*(^m>2;B$^UsU zG&MA`1OUYSr-HJm0Du8O073#HfuI1Q0-^(B0Ad1S0pa|^{+smwh6VsIK>`4Pf%~6< z|7re9>PPv1lXK5@@rHCq8Ch|4GZ!k&BFvCvBE&Wc31%RKB*_S-5s@G;2|xhS^bhw( z5I}>RBqE@qAfoc6q6#d`ua1O{^oORRqG~S)>~g1vT7B-+=^%RRxvj{6{MxOH+xECz zs!%SI%i(gV>< zthejqf@@D-gLtRYs;ud)KK~<&6ERT3%SyY3#^Z9LLpzR_EhpzC!JrX+Y|!RWrtB@n z-hXL_dOwg+?7ab=YznOs_Q=dqlQdIb&|*7A@>j^_Q{|OhUrSzZj__Xj1+>ID{uU4+O0VTjSCI}udD2NTL

Y_z9%WvvD)e^g~(ZvB8E-Q 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