Skip to content

Commit 7d2f8b2

Browse files
authored
Merge pull request #1412 from gcmoreira/linux_task_parent_pid_fix
Linux: Fix task parent pid in several plugins
2 parents 992ba3e + e035faa commit 7d2f8b2

File tree

8 files changed

+34
-37
lines changed

8 files changed

+34
-37
lines changed

volatility3/framework/constants/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# We use the SemVer 2.0.0 versioning scheme
22
VERSION_MAJOR = 2 # Number of releases of the library with a breaking change
3-
VERSION_MINOR = 12 # Number of changes that only add to the interface
3+
VERSION_MINOR = 13 # Number of changes that only add to the interface
44
VERSION_PATCH = 0 # Number of changes that do not change the interface
55
VERSION_SUFFIX = ""
66

volatility3/framework/plugins/linux/capabilities.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ def astuple(self) -> Tuple:
4949
class Capabilities(plugins.PluginInterface):
5050
"""Lists process capabilities"""
5151

52-
_required_framework_version = (2, 0, 0)
53-
_version = (1, 0, 1)
52+
_required_framework_version = (2, 13, 0)
53+
_version = (1, 1, 0)
5454

5555
@classmethod
5656
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -136,7 +136,7 @@ def get_task_capabilities(
136136
comm=utility.array_to_string(task.comm),
137137
pid=int(task.pid),
138138
tgid=int(task.tgid),
139-
ppid=int(task.parent.pid),
139+
ppid=int(task.get_parent_pid()),
140140
euid=int(task.cred.euid),
141141
)
142142

volatility3/framework/plugins/linux/envars.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
class Envars(plugins.PluginInterface):
1717
"""Lists processes with their environment variables"""
1818

19-
_required_framework_version = (2, 0, 0)
20-
_version = (1, 0, 1)
19+
_required_framework_version = (2, 13, 0)
20+
_version = (1, 1, 0)
2121

2222
@classmethod
2323
def get_requirements(cls):
@@ -48,15 +48,7 @@ def _generator(self, tasks):
4848

4949
# get process name as string
5050
name = utility.array_to_string(task.comm)
51-
52-
# try and get task parent
53-
try:
54-
ppid = task.parent.pid
55-
except exceptions.InvalidAddressException:
56-
vollog.debug(
57-
f"Unable to read parent pid for task {pid} {name}, setting ppid to 0."
58-
)
59-
ppid = 0
51+
ppid = task.get_parent_pid()
6052

6153
# kernel threads never have an mm as they do not have userland mappings
6254
try:

volatility3/framework/plugins/linux/psaux.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
class PsAux(plugins.PluginInterface):
1515
"""Lists processes with their command line arguments"""
1616

17-
_required_framework_version = (2, 0, 0)
18-
_version = (1, 0, 1)
17+
_required_framework_version = (2, 13, 0)
18+
_version = (1, 1, 0)
1919

2020
@classmethod
2121
def get_requirements(cls):
@@ -98,14 +98,8 @@ def _generator(self, tasks):
9898
# walk the process list and report the arguments
9999
for task in tasks:
100100
pid = task.pid
101-
102-
try:
103-
ppid = task.parent.pid
104-
except exceptions.InvalidAddressException:
105-
ppid = 0
106-
101+
ppid = task.get_parent_pid()
107102
name = utility.array_to_string(task.comm)
108-
109103
args = self._get_command_line_args(task, name)
110104

111105
yield (0, (pid, ppid, name, args))

volatility3/framework/plugins/linux/pslist.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
class PsList(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
1818
"""Lists the processes present in a particular linux memory image."""
1919

20-
_required_framework_version = (2, 0, 0)
21-
_version = (3, 0, 0)
20+
_required_framework_version = (2, 13, 0)
21+
_version = (3, 1, 0)
2222

2323
@classmethod
2424
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -95,7 +95,7 @@ def get_task_fields(
9595
"""
9696
pid = task.tgid
9797
tid = task.pid
98-
ppid = task.parent.tgid if task.parent else 0
98+
ppid = task.get_parent_pid()
9999
name = utility.array_to_string(task.comm)
100100
start_time = task.get_create_time()
101101
if decorate_comm:

volatility3/framework/plugins/linux/psscan.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class DescExitStateEnum(Enum):
2727
class PsScan(interfaces.plugins.PluginInterface):
2828
"""Scans for processes present in a particular linux image."""
2929

30-
_required_framework_version = (2, 0, 0)
31-
_version = (1, 0, 1)
30+
_required_framework_version = (2, 13, 0)
31+
_version = (1, 1, 0)
3232

3333
@classmethod
3434
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -52,10 +52,7 @@ def _get_task_fields(
5252
"""
5353
pid = task.tgid
5454
tid = task.pid
55-
ppid = 0
56-
57-
if task.parent.is_readable():
58-
ppid = task.parent.tgid
55+
ppid = task.get_parent_pid()
5956
name = utility.array_to_string(task.comm)
6057
exit_state = DescExitStateEnum(task.exit_state).name
6158

volatility3/framework/plugins/linux/pstree.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class PsTree(interfaces.plugins.PluginInterface):
1212
"""Plugin for listing processes in a tree based on their parent process
1313
ID."""
1414

15-
_required_framework_version = (2, 0, 0)
16-
_version = (1, 0, 1)
15+
_required_framework_version = (2, 13, 0)
16+
_version = (1, 1, 0)
1717

1818
@classmethod
1919
def get_requirements(cls):
@@ -56,9 +56,9 @@ def find_level(self, pid: int) -> None:
5656
seen = set([pid])
5757
level = 0
5858
proc = self._tasks.get(pid)
59-
while proc and proc.parent and proc.parent.pid not in seen:
59+
while proc and proc.get_parent_pid() not in seen:
6060
if proc.is_thread_group_leader:
61-
parent_pid = proc.parent.pid
61+
parent_pid = proc.get_parent_pid()
6262
else:
6363
parent_pid = proc.tgid
6464

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,20 @@ def get_create_time(self) -> datetime.datetime:
633633
# root time namespace, not within the task's own time namespace
634634
return boottime + task_start_time_timedelta
635635

636+
def get_parent_pid(self) -> int:
637+
"""Returns the parent process ID (PPID)
638+
639+
This method replicates the Linux kernel's `getppid` syscall behavior.
640+
Avoid using `task.parent`; instead, use this function for accurate results.
641+
"""
642+
643+
if self.real_parent and self.real_parent.is_readable():
644+
ppid = self.real_parent.pid
645+
else:
646+
ppid = 0
647+
648+
return ppid
649+
636650

637651
class fs_struct(objects.StructType):
638652
def get_root_dentry(self):

0 commit comments

Comments
 (0)