Skip to content

Commit

Permalink
Merge pull request #1544 from gcmoreira/linux_parity_release_harden_v…
Browse files Browse the repository at this point in the history
…ma_enumeration

Linux: Ensure VMA enumration functions yield only valid objects consistently
  • Loading branch information
ikelos authored Jan 17, 2025
2 parents adf81bc + 0d97151 commit adea50a
Showing 1 changed file with 32 additions and 14 deletions.
46 changes: 32 additions & 14 deletions volatility3/framework/symbols/linux/extensions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -811,23 +811,30 @@ def get_mmap_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
def _get_mmap_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Returns an iterator for the mmap list member of an mm_struct. Use this only if
required, get_vma_iter() will choose the correct _get_maple_tree_iter() or
_get_mmap_iter() automatically as required."""
_get_mmap_iter() automatically as required.
Yields:
vm_area_struct objects
"""

if not self.has_member("mmap"):
raise AttributeError(
"_get_mmap_iter called on mm_struct where no mmap member exists."
)
if not self.mmap:
vma_pointer = self.mmap
if not (vma_pointer and vma_pointer.is_readable()):
return None
yield self.mmap
vma_object = vma_pointer.dereference()
yield vma_object

seen = {self.mmap.vol.offset}
link = self.mmap.vm_next
seen = {vma_pointer}
vma_pointer = vma_pointer.vm_next

while link != 0 and link.vol.offset not in seen:
yield link
seen.add(link.vol.offset)
link = link.vm_next
while vma_pointer and vma_pointer.is_readable() and vma_pointer not in seen:
vma_object = vma_pointer.dereference()
yield vma_object
seen.add(vma_pointer)
vma_pointer = vma_pointer.vm_next

# TODO: As of version 3.0.0 this method should be removed
def get_maple_tree_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
Expand All @@ -842,28 +849,39 @@ def get_maple_tree_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
def _get_maple_tree_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
"""Returns an iterator for the mm_mt member of an mm_struct. Use this only if
required, get_vma_iter() will choose the correct _get_maple_tree_iter() or
get_mmap_iter() automatically as required."""
get_mmap_iter() automatically as required.
Yields:
vm_area_struct objects
"""

if not self.has_member("mm_mt"):
raise AttributeError(
"_get_maple_tree_iter called on mm_struct where no mm_mt member exists."
)
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 = self._context.object(
# 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,
)
yield vma
yield vma_object

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."""
"""Returns an iterator for the VMAs in an mm_struct.
Automatically choosing the mmap or mm_mt as required.
Yields:
vm_area_struct objects
"""

if self.has_member("mmap"):
# kernels < 6.1
yield from self._get_mmap_iter()
elif self.has_member("mm_mt"):
# kernels >= 6.1 d4af56c5c7c6781ca6ca8075e2cf5bc119ed33d1
yield from self._get_maple_tree_iter()
else:
raise AttributeError("Unable to find mmap or mm_mt in mm_struct")
Expand Down

0 comments on commit adea50a

Please sign in to comment.