Skip to content

Commit

Permalink
linux: ensure process listing functions yield only valid tasks
Browse files Browse the repository at this point in the history
gcmoreira committed Jan 13, 2025
1 parent a677714 commit 6817d2c
Showing 2 changed files with 36 additions and 1 deletion.
5 changes: 4 additions & 1 deletion volatility3/framework/plugins/linux/pslist.py
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Lists the processes present in a particular linux memory image."""

_required_framework_version = (2, 13, 0)
_version = (4, 0, 0)
_version = (4, 1, 0)

@classmethod
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -250,6 +250,9 @@ def list_tasks(

# Note that the init_task itself is not yielded, since "ps" also never shows it.
for task in init_task.tasks:
if not task.is_valid():
continue

if filter_func(task):
continue

32 changes: 32 additions & 0 deletions volatility3/framework/symbols/linux/extensions/__init__.py
Original file line number Diff line number Diff line change
@@ -307,6 +307,36 @@ def section_strtab(self):


class task_struct(generic.GenericIntelProcess):
def is_valid(self) -> bool:
layer = self._context.layers[self.vol.layer_name]
# Make sure the entire task content is readable
if not layer.is_valid(self.vol.offset, self.vol.size):
return False

if self.pid < 0:
return False

if not (self.signal and self.signal.is_readable()):
return False

if not (self.nsproxy and self.nsproxy.is_readable()):
return False

if not (self.real_parent and self.real_parent.is_readable()):
return False

if self.active_mm and not self.active_mm.is_readable():
return False

if self.mm:
if not self.mm.is_readable():
return False

if self.mm != self.active_mm:
return False

return True

def add_process_layer(
self, config_prefix: Optional[str] = None, preferred_name: Optional[str] = None
) -> Optional[str]:
@@ -401,6 +431,8 @@ def get_threads(self) -> Iterable[interfaces.objects.ObjectInterface]:
tasks_iterable = self._get_tasks_iterable()
threads_seen = set([self.vol.offset])
for task in tasks_iterable:
if not task.is_valid():
continue
if task.vol.offset not in threads_seen:
threads_seen.add(task.vol.offset)
yield task

0 comments on commit 6817d2c

Please sign in to comment.