Skip to content

Commit

Permalink
Exceptions on malformed ELF header contents
Browse files Browse the repository at this point in the history
  • Loading branch information
sevaa committed Apr 16, 2024
1 parent f6ad930 commit a36f87e
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
33 changes: 31 additions & 2 deletions elftools/elf/elffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,12 +588,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 < (0x40 if self.elfclass == 64 else 0x28):
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 < (0x38 if self.elfclass == 64 else 0x20):
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,6 +689,10 @@ def _make_symbol_table_section(self, section_header, name):
""" Create a SymbolTableSection
"""
linked_strtab_index = section_header['sh_link']
# Lookahead to validate linked section type
linked_section_type = self._get_section_header(linked_strtab_index)['sh_type']
if linked_section_type != 'SHT_STRTAB':
raise ELFError("SHT_SYMTAB section points at section %d of type %s, expected SHT_STRTAB" % (linked_strtab_index, linked_section_type))
strtab_section = self.get_section(linked_strtab_index)
return SymbolTableSection(
section_header, name,
Expand All @@ -701,6 +711,10 @@ def _make_sunwsyminfo_table_section(self, section_header, name):
""" Create a SUNWSyminfoTableSection
"""
linked_strtab_index = section_header['sh_link']
# Lookahead to validate linked section type
linked_section_type = self._get_section_header(linked_strtab_index)['sh_type']
if linked_section_type not in ('SHT_SYMTAB', 'SHT_DYNSYM'):
raise ELFError("SHT_SYNW_syminfo points at section %d of type %s, expected SHT_SYMTAB/SHT_DYNSYM" % (linked_strtab_index, linked_section_type))
strtab_section = self.get_section(linked_strtab_index)
return SUNWSyminfoTableSection(
section_header, name,
Expand All @@ -711,6 +725,10 @@ def _make_gnu_verneed_section(self, section_header, name):
""" Create a GNUVerNeedSection
"""
linked_strtab_index = section_header['sh_link']
# Lookahead to validate linked section type
linked_section_type = self._get_section_header(linked_strtab_index)['sh_type']
if linked_section_type != 'SHT_STRTAB':
raise ELFError("SHT_GNU_verneed section points at section %d of type %s, expected SHT_STRTAB" % (linked_strtab_index, linked_section_type))
strtab_section = self.get_section(linked_strtab_index)
return GNUVerNeedSection(
section_header, name,
Expand All @@ -721,6 +739,10 @@ def _make_gnu_verdef_section(self, section_header, name):
""" Create a GNUVerDefSection
"""
linked_strtab_index = section_header['sh_link']
# Lookahead to validate linked section type
linked_section_type = self._get_section_header(linked_strtab_index)['sh_type']
if linked_section_type != 'SHT_STRTAB':
raise ELFError("SHT_GNU_verdef section points at section %d of type %s, expected SHT_STRTAB" % (linked_strtab_index, linked_section_type))
strtab_section = self.get_section(linked_strtab_index)
return GNUVerDefSection(
section_header, name,
Expand All @@ -739,13 +761,20 @@ 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']
# Lookahead to validate linked section type
linked_section_type = self._get_section_header(linked_symtab_index)['sh_type']
if linked_section_type not in ('SHT_SYMTAB', 'SHT_DYNSYM'):
raise ELFError("SHT_HASH section points at section %d of type %s, expected SHT_SYMTAB/SHT_DYNSYM" % (linked_symtab_index, linked_section_type))
symtab_section = self.get_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']
linked_section_type = self._get_section_header(linked_symtab_index)['sh_type']
if linked_section_type not in ('SHT_SYMTAB', 'SHT_DYNSYM'):
raise ELFError("SHT_GNU_HASH section points at section %d of type %s, expected SHT_SYMTAB/SHT_DYNSYM" % (linked_symtab_index, linked_section_type))
symtab_section = self.get_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 a36f87e

Please sign in to comment.