Merge pull request #1654 from volatilityfoundation/fix_vma_iteration

Fix bugs in Linux memory region enumeration
This commit is contained in:
ikelos
2025-03-05 21:09:14 +00:00
committed by GitHub
@@ -849,7 +849,7 @@ class maple_tree(objects.StructType):
expected_maple_tree_depth,
seen=None,
current_depth=1,
):
) -> Optional[int]:
"""Recursively parse Maple Tree Nodes and yield all non empty slots"""
# Create seen set if it does not exist, e.g. on the first call into this recursive function. This
@@ -898,7 +898,8 @@ class maple_tree(objects.StructType):
node_parent_pointer = node_parent_mte & ~(self.MAPLE_NODE_POINTER_MASK)
# verify that the node_parent_pointer correctly points to the parent
assert node_parent_pointer == parent
if node_parent_pointer != parent:
return None
# create a node object
node = self._context.object(
@@ -1008,15 +1009,21 @@ class mm_struct(objects.StructType):
)
symbol_table_name = self.get_symbol_table_name()
for vma_pointer in self.mm_mt.get_slot_iter():
# Convert pointer to vm_area_struct and yield
vma_object = self._context.object(
symbol_table_name + constants.BANG + "vm_area_struct",
layer_name=self.vol.native_layer_name,
offset=vma_pointer,
)
try:
vma_object = vma_pointer.dereference().cast(
symbol_table_name + constants.BANG + "vm_area_struct"
)
except exceptions.InvalidAddressException:
continue
# The slots will hold values related to their slot if they are invalid
# Before this check, this function was returning objects on the first page of memory...
if vma_object.vol.offset < 0x1000:
continue
yield vma_object
def get_vma_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
def _do_get_vma_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Returns an iterator for the VMAs in an mm_struct.
Automatically choosing the mmap or mm_mt as required.
@@ -1033,6 +1040,23 @@ class mm_struct(objects.StructType):
else:
raise AttributeError("Unable to find mmap or mm_mt in mm_struct")
def get_vma_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Returns an iterator for the VMAs in an mm_struct.
Automatically choosing the mmap or mm_mt as required.
Yields:
vm_area_struct objects
"""
for vma in self._do_get_vma_iter():
try:
vma.vm_start
vma.vm_end
vma.get_protection()
yield vma
except exceptions.InvalidAddressException:
vollog.debug(f"Skipping invalid vm_area_struct at {vma.vol.offset:#x}")
class super_block(objects.StructType):
# include/linux/kdev_t.h