Skip to content

Commit

Permalink
Exceptions on malformed ELF header contents (#552)
Browse files Browse the repository at this point in the history
* Exceptions on malformed ELF header contents

* Code cleanup

* Min table entry size retrieved from struct
  • Loading branch information
sevaa committed Apr 17, 2024
1 parent f6ad930 commit 9257a0f
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 8 deletions.
42 changes: 34 additions & 8 deletions elftools/elf/elffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,26 @@ def get_section(self, n):
"""
section_header = self._get_section_header(n)
return self._make_section(section_header)

def _get_linked_symtab_section(self, n):
""" Get the section at index #n from the file, throws
if it's not a SYMTAB/DYNTAB.
Used for resolving section links with target type validation.
"""
section_header = self._get_section_header(n)
if section_header['sh_type'] not in ('SHT_SYMTAB', 'SHT_DYNSYM'):
raise ELFError("Section points at section %d of type %s, expected SHT_SYMTAB/SHT_DYNSYM" % (n, section_header['sh_type']))
return self._make_section(section_header)

def _get_linked_strtab_section(self, n):
""" Get the section at index #n from the file, throws
if it's not a STRTAB.
Used for resolving section links with target type validation.
"""
section_header = self._get_section_header(n)
if section_header['sh_type'] != 'SHT_STRTAB':
raise ELFError("SHT_SYMTAB section points at section %d of type %s, expected SHT_STRTAB" % (n, section_header['sh_type']))
return self._make_section(section_header)

def get_section_by_name(self, name):
""" Get a section from the file, by name. Return None if no such
Expand Down Expand Up @@ -588,12 +608,18 @@ def _identify_file(self):
def _section_offset(self, n):
""" Compute the offset of section #n in the file
"""
return self['e_shoff'] + n * self['e_shentsize']
shentsize = self['e_shentsize']
if self['e_shoff'] > 0 and shentsize < self.structs.Elf_Shdr.sizeof():
raise ELFError('Too small e_shentsize: %s' % shentsize)
return self['e_shoff'] + n * shentsize

def _segment_offset(self, n):
""" Compute the offset of segment #n in the file
"""
return self['e_phoff'] + n * self['e_phentsize']
phentsize = self['e_phentsize']
if self['e_phoff'] > 0 and phentsize < self.structs.Elf_Phdr.sizeof():
raise ELFError('Too small e_phentsize: %s' % phentsize)
return self['e_phoff'] + n * phentsize

def _make_segment(self, segment_header):
""" Create a Segment object of the appropriate type
Expand Down Expand Up @@ -683,7 +709,7 @@ def _make_symbol_table_section(self, section_header, name):
""" Create a SymbolTableSection
"""
linked_strtab_index = section_header['sh_link']
strtab_section = self.get_section(linked_strtab_index)
strtab_section = self._get_linked_strtab_section(linked_strtab_index)
return SymbolTableSection(
section_header, name,
elffile=self,
Expand All @@ -701,7 +727,7 @@ def _make_sunwsyminfo_table_section(self, section_header, name):
""" Create a SUNWSyminfoTableSection
"""
linked_strtab_index = section_header['sh_link']
strtab_section = self.get_section(linked_strtab_index)
strtab_section = self._get_linked_symtab_section(linked_strtab_index)
return SUNWSyminfoTableSection(
section_header, name,
elffile=self,
Expand All @@ -711,7 +737,7 @@ def _make_gnu_verneed_section(self, section_header, name):
""" Create a GNUVerNeedSection
"""
linked_strtab_index = section_header['sh_link']
strtab_section = self.get_section(linked_strtab_index)
strtab_section = self._get_linked_strtab_section(linked_strtab_index)
return GNUVerNeedSection(
section_header, name,
elffile=self,
Expand All @@ -721,7 +747,7 @@ def _make_gnu_verdef_section(self, section_header, name):
""" Create a GNUVerDefSection
"""
linked_strtab_index = section_header['sh_link']
strtab_section = self.get_section(linked_strtab_index)
strtab_section = self._get_linked_strtab_section(linked_strtab_index)
return GNUVerDefSection(
section_header, name,
elffile=self,
Expand All @@ -739,14 +765,14 @@ def _make_gnu_versym_section(self, section_header, name):

def _make_elf_hash_section(self, section_header, name):
linked_symtab_index = section_header['sh_link']
symtab_section = self.get_section(linked_symtab_index)
symtab_section = self._get_linked_symtab_section(linked_symtab_index)
return ELFHashSection(
section_header, name, self, symtab_section
)

def _make_gnu_hash_section(self, section_header, name):
linked_symtab_index = section_header['sh_link']
symtab_section = self.get_section(linked_symtab_index)
symtab_section = self._get_linked_symtab_section(linked_symtab_index)
return GNUHashSection(
section_header, name, self, symtab_section
)
Expand Down
17 changes: 17 additions & 0 deletions test/test_bogus_entry_size.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import unittest
import os
from elftools.common.exceptions import ELFError
from elftools.elf.elffile import ELFFile

class TestSectionHeaderEntrySizeCheck(unittest.TestCase):
def test_size_check(self):
test_file = os.path.join('test', 'testfiles_for_unittests', 'section_header_bogus_size.elf')
with open(test_file, 'rb') as f:
# This file contains a nonblank section header table and
# claims header table entry size is zero.
with self.assertRaises(ELFError):
elffile = ELFFile(f)
elffile.has_dwarf_info()

if __name__ == '__main__':
unittest.main()
16 changes: 16 additions & 0 deletions test/test_section_self_link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import unittest
import os
from elftools.common.exceptions import ELFError
from elftools.elf.elffile import ELFFile

class TestSectionSelfLink(unittest.TestCase):
def test_self_link(self):
test_file = os.path.join('test', 'testfiles_for_unittests', 'section_link_to_self.elf')
with open(test_file, 'rb') as f:
# This file contains a SHT_HASH section with sh_link pointing at self.
# The spec says SHT_hash should point at a symtab-type section.
with self.assertRaises(ELFError):
ELFFile(f).has_dwarf_info()

if __name__ == '__main__':
unittest.main()
Binary file not shown.
Binary file not shown.

0 comments on commit 9257a0f

Please sign in to comment.