Linux: Ensure VMA enumration functions yield only valid objects consistently

This commit is contained in:
Gustavo Moreira
2025-01-13 17:15:37 +11:00
parent a6777146f6
commit 0d9715136c
@@ -811,23 +811,30 @@ class mm_struct(objects.StructType):
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]:
@@ -842,7 +849,11 @@ class mm_struct(objects.StructType):
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(
@@ -850,20 +861,27 @@ 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 = 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")