Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions elftools/elf/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from elftools.construct.lib.container import Container

from ..common.exceptions import ELFCompressionError
from ..common.exceptions import ELFCompressionError, ELFError
from ..common.utils import elf_assert, parse_cstring_from_stream, struct_parse
from .constants import SH_FLAGS
from .notes import iter_notes
Expand Down Expand Up @@ -156,7 +156,15 @@ def get_string(self, offset: int) -> str:
""" Get the string stored at the given offset in this string table.
"""
table_offset = self['sh_offset']
s = parse_cstring_from_stream(self.stream, table_offset + offset)
try:
s = parse_cstring_from_stream(self.stream, table_offset + offset)
except (OverflowError, ValueError, OSError) as e:
# A corrupt name offset can make the absolute stream position out
# of range for stream.seek(). Depending on the stream type this
# raises OverflowError/ValueError (BytesIO) or ValueError/OSError
# (a real file). Surface any of them as an ELFError.
raise ELFError(
f'Invalid string offset {offset} in string table') from e
return s.decode('utf-8', errors='replace') if s else ''


Expand Down
18 changes: 17 additions & 1 deletion test/test_corrupt_files.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
"""
Test that elftools does not fail to load corrupted ELF files
"""
import io
import os
import unittest

from elftools.common.exceptions import ELFParseError
from elftools.common.exceptions import ELFError, ELFParseError
from elftools.elf.elffile import ELFFile


class TestCorruptFile(unittest.TestCase):
def test_string_table_offset_out_of_range(self):
""" A corrupt (out-of-range) string-table offset must raise ELFError,
not a raw OverflowError/ValueError from stream.seek().
"""
filepath = os.path.join(
'test', 'testfiles_for_readelf', 'simple_aarch64_gcc.o.elf')
with open(filepath, 'rb') as f:
stream = io.BytesIO(f.read())
elf = ELFFile(stream)
strtab = elf.get_section(elf['e_shstrndx'])
with self.assertRaises(ELFError):
strtab.get_string(10 ** 30) # huge -> seek OverflowError
with self.assertRaises(ELFError):
strtab.get_string(-(10 ** 18)) # negative -> seek ValueError

def test_elffile_init(self):
""" Test that ELFFile does not crash when parsing an ELF file with corrupt e_shoff and/or e_shnum
"""
Expand Down
Loading