Skip to content

Commit adea50a

Browse files
authored
Merge pull request #1544 from gcmoreira/linux_parity_release_harden_vma_enumeration
Linux: Ensure VMA enumration functions yield only valid objects consistently
2 parents adf81bc + 0d97151 commit adea50a

File tree

1 file changed

+32
-14
lines changed
  • volatility3/framework/symbols/linux/extensions

1 file changed

+32
-14
lines changed

volatility3/framework/symbols/linux/extensions/__init__.py

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -811,23 +811,30 @@ def get_mmap_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
811811
def _get_mmap_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
812812
"""Returns an iterator for the mmap list member of an mm_struct. Use this only if
813813
required, get_vma_iter() will choose the correct _get_maple_tree_iter() or
814-
_get_mmap_iter() automatically as required."""
814+
_get_mmap_iter() automatically as required.
815+
816+
Yields:
817+
vm_area_struct objects
818+
"""
815819

816820
if not self.has_member("mmap"):
817821
raise AttributeError(
818822
"_get_mmap_iter called on mm_struct where no mmap member exists."
819823
)
820-
if not self.mmap:
824+
vma_pointer = self.mmap
825+
if not (vma_pointer and vma_pointer.is_readable()):
821826
return None
822-
yield self.mmap
827+
vma_object = vma_pointer.dereference()
828+
yield vma_object
823829

824-
seen = {self.mmap.vol.offset}
825-
link = self.mmap.vm_next
830+
seen = {vma_pointer}
831+
vma_pointer = vma_pointer.vm_next
826832

827-
while link != 0 and link.vol.offset not in seen:
828-
yield link
829-
seen.add(link.vol.offset)
830-
link = link.vm_next
833+
while vma_pointer and vma_pointer.is_readable() and vma_pointer not in seen:
834+
vma_object = vma_pointer.dereference()
835+
yield vma_object
836+
seen.add(vma_pointer)
837+
vma_pointer = vma_pointer.vm_next
831838

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

847858
if not self.has_member("mm_mt"):
848859
raise AttributeError(
849860
"_get_maple_tree_iter called on mm_struct where no mm_mt member exists."
850861
)
851862
symbol_table_name = self.get_symbol_table_name()
852863
for vma_pointer in self.mm_mt.get_slot_iter():
853-
# convert pointer to vm_area_struct and yield
854-
vma = self._context.object(
864+
# Convert pointer to vm_area_struct and yield
865+
vma_object = self._context.object(
855866
symbol_table_name + constants.BANG + "vm_area_struct",
856867
layer_name=self.vol.native_layer_name,
857868
offset=vma_pointer,
858869
)
859-
yield vma
870+
yield vma_object
860871

861872
def get_vma_iter(self) -> Iterable[interfaces.objects.ObjectInterface]:
862-
"""Returns an iterator for the VMAs in an mm_struct. Automatically choosing the mmap or mm_mt as required."""
873+
"""Returns an iterator for the VMAs in an mm_struct.
874+
Automatically choosing the mmap or mm_mt as required.
875+
876+
Yields:
877+
vm_area_struct objects
878+
"""
863879

864880
if self.has_member("mmap"):
881+
# kernels < 6.1
865882
yield from self._get_mmap_iter()
866883
elif self.has_member("mm_mt"):
884+
# kernels >= 6.1 d4af56c5c7c6781ca6ca8075e2cf5bc119ed33d1
867885
yield from self._get_maple_tree_iter()
868886
else:
869887
raise AttributeError("Unable to find mmap or mm_mt in mm_struct")

0 commit comments

Comments
 (0)