Skip to content

Commit 87fe344

Browse files
committed
Linux: Add support for mount namespace in kernels 6.8+. This fixes #1187
1 parent 4578434 commit 87fe344

File tree

2 files changed

+68
-7
lines changed

2 files changed

+68
-7
lines changed

volatility3/framework/symbols/linux/__init__.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,36 @@ def get_module_from_volobj_type(
425425
kernel = context.modules[kernel_module_name]
426426

427427
return kernel
428+
429+
430+
class RBTree(object):
431+
"""Simple Red-Black tree abstraction"""
432+
433+
def __init__(self, root):
434+
self.root = root
435+
436+
def _walk_nodes(self, root_node) -> Iterator[int]:
437+
"""Traverses the Red-Black tree from the root node and yields a pointer to each
438+
node in this tree.
439+
440+
Args:
441+
root_node: A Red-Black tree node from which to start descending
442+
443+
Yields:
444+
A pointer to every node descending from the specified root node
445+
"""
446+
if not root_node:
447+
return
448+
449+
yield root_node
450+
yield from self._walk_nodes(root_node.rb_left)
451+
yield from self._walk_nodes(root_node.rb_right)
452+
453+
def get_nodes(self) -> Iterator[int]:
454+
"""Yields a pointer to each node in the Red-Black tree
455+
456+
Yields:
457+
A pointer to every node in the Red-Black tree
458+
"""
459+
460+
yield from self._walk_nodes(root_node=self.root.rb_node)

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

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,14 +1299,42 @@ def get_inode(self):
12991299
else:
13001300
raise AttributeError("Unable to find mnt_namespace inode")
13011301

1302-
def get_mount_points(self):
1302+
def get_mount_points(
1303+
self,
1304+
) -> Iterator[interfaces.objects.ObjectInterface]:
1305+
"""Yields the mount points for this mount namespace.
1306+
1307+
Yields:
1308+
mount struct instances
1309+
"""
13031310
table_name = self.vol.type_name.split(constants.BANG)[0]
1304-
mnt_type = table_name + constants.BANG + "mount"
1305-
if not self._context.symbol_space.has_type(mnt_type):
1306-
# Old kernels ~ 2.6
1307-
mnt_type = table_name + constants.BANG + "vfsmount"
1308-
for mount in self.list.to_list(mnt_type, "mnt_list"):
1309-
yield mount
1311+
1312+
if self.has_member("list"):
1313+
# kernels < 6.8
1314+
mnt_type = table_name + constants.BANG + "mount"
1315+
if not self._context.symbol_space.has_type(mnt_type):
1316+
# In kernels < 3.3, the 'mount' struct didn't exist, and the 'mnt_list'
1317+
# member was part of the 'vfsmount' struct.
1318+
mnt_type = table_name + constants.BANG + "vfsmount"
1319+
1320+
yield from self.list.to_list(mnt_type, "mnt_list")
1321+
elif (
1322+
self.has_member("mounts")
1323+
and self.mounts.vol.type_name == table_name + constants.BANG + "rb_root"
1324+
):
1325+
# kernels >= 6.8
1326+
vmlinux = linux.LinuxUtilities.get_module_from_volobj_type(
1327+
self._context, self
1328+
)
1329+
for node in linux.RBTree(self.mounts).get_nodes():
1330+
mnt = linux.LinuxUtilities.container_of(
1331+
node, "mount", "mnt_list", vmlinux
1332+
)
1333+
yield mnt
1334+
else:
1335+
raise exceptions.VolatilityException(
1336+
"Unsupported kernel mount namespace implementation"
1337+
)
13101338

13111339

13121340
class net(objects.StructType):

0 commit comments

Comments
 (0)