Skip to content

Commit 4009c6b

Browse files
committed
add section address sanity check
1 parent ed8af0a commit 4009c6b

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

volatility3/framework/symbols/linux/utilities/module_extract.py

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010
Dict,
1111
)
1212

13+
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
1314
from volatility3 import framework
1415
from volatility3.framework import (
1516
interfaces,
1617
exceptions,
1718
symbols,
1819
)
20+
from volatility3.framework.configuration import requirements
1921
from volatility3.framework.constants import linux as linux_constants
2022
from volatility3.framework.symbols.linux import extensions
2123

@@ -38,11 +40,21 @@
3840
class ModuleExtract(interfaces.configuration.VersionableInterface):
3941
"""Extracts Linux kernel module structures into an analyzable ELF file"""
4042

41-
_version = (1, 0, 1)
43+
_version = (1, 0, 2)
4244
_required_framework_version = (2, 25, 0)
4345

4446
framework.require_interface_version(*_required_framework_version)
4547

48+
@classmethod
49+
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
50+
return [
51+
requirements.VersionRequirement(
52+
name="linux_utilities_modules",
53+
component=linux_utilities_modules.Modules,
54+
version=(3, 0, 2),
55+
),
56+
]
57+
4658
@classmethod
4759
def _find_section(
4860
cls, section_lookups: List[Tuple[str, int, int, int]], sym_address: int
@@ -237,17 +249,32 @@ def _parse_sections(
237249
The data of .strtab is read directly off the module structure and not its section
238250
as the section from the original module has no meaning after loading as the kernel does not reference it.
239251
"""
252+
kernel = context.modules[vmlinux_name]
253+
kernel_layer = context.layers[kernel.layer_name]
254+
modules_addr_min, modules_addr_max = (
255+
linux_utilities_modules.Modules.get_modules_memory_boundaries(
256+
context, vmlinux_name
257+
)
258+
)
259+
modules_addr_min &= kernel_layer.address_mask
260+
modules_addr_max &= kernel_layer.address_mask
261+
240262
original_sections = {}
241263
for index, section in enumerate(module.get_sections()):
264+
# Extra sanity check, to prevent OOM on heavily smeared samples at line
265+
# "size = next_address - address"
266+
if (
267+
not modules_addr_min
268+
<= kernel_layer.address_mask & section.address
269+
< modules_addr_max
270+
):
271+
continue
242272
name = section.get_name()
243273
original_sections[section.address] = name
244274

245275
if not original_sections:
246276
return None
247277

248-
kernel = context.modules[vmlinux_name]
249-
kernel_layer = context.layers[kernel.layer_name]
250-
251278
if symbols.symbol_table_is_64bit(context, kernel.symbol_table_name):
252279
sym_type = "Elf64_Sym"
253280
elf_hdr_type = "Elf64_Ehdr"

0 commit comments

Comments
 (0)