Skip to content

Commit 15a51cf

Browse files
committed
Linux - Add hlist_head object extension. Fix #1313
1 parent a10fb5b commit 15a51cf

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

volatility3/framework/symbols/linux/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def __init__(self, *args, **kwargs) -> None:
2222
# Set-up Linux specific types
2323
self.set_type_class("file", extensions.struct_file)
2424
self.set_type_class("list_head", extensions.list_head)
25+
self.set_type_class("hlist_head", extensions.hlist_head)
2526
self.set_type_class("mm_struct", extensions.mm_struct)
2627
self.set_type_class("super_block", extensions.super_block)
2728
self.set_type_class("task_struct", extensions.task_struct)

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

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,7 +844,7 @@ def get_subdirs(self) -> interfaces.objects.ObjectInterface:
844844
if self.has_member("d_sib") and self.has_member("d_children"):
845845
# kernels >= 6.8
846846
walk_member = "d_sib"
847-
list_head_member = self.d_children.first
847+
list_head_member = self.d_children
848848
elif self.has_member("d_child") and self.has_member("d_subdirs"):
849849
# 2.5.0 <= kernels < 6.8
850850
walk_member = "d_child"
@@ -961,6 +961,43 @@ def __iter__(self) -> Iterator[interfaces.objects.ObjectInterface]:
961961
return self.to_list(self.vol.parent.vol.type_name, self.vol.member_name)
962962

963963

964+
class hlist_head(objects.StructType, collections.abc.Iterable):
965+
def to_list(
966+
self,
967+
symbol_type: str,
968+
member: str,
969+
) -> Iterator[interfaces.objects.ObjectInterface]:
970+
"""Returns an iterator of the entries in the list.
971+
972+
This is a doubly linked list; however, it is not circular, so the 'forward' field
973+
doesn't make sense. Also, the sentinel concept doesn't make sense here either;
974+
unlike list_head, the head and nodes each have their own distinct types. A list_head
975+
cannot be a node by itself.
976+
- The 'pprev' of the first 'hlist_node' points to the 'hlist_head', not to the last node.
977+
- The last element 'next' member is NULL
978+
979+
Args:
980+
symbol_type: Type of the list elements
981+
member: Name of the list_head member in the list elements
982+
983+
Yields:
984+
Objects of the type specified via the "symbol_type" argument.
985+
986+
"""
987+
vmlinux = linux.LinuxUtilities.get_module_from_volobj_type(self._context, self)
988+
989+
current = self.first
990+
while current and current.is_readable():
991+
yield linux.LinuxUtilities.container_of(
992+
current, symbol_type, member, vmlinux
993+
)
994+
995+
current = current.next
996+
997+
def __iter__(self) -> Iterator[interfaces.objects.ObjectInterface]:
998+
return self.to_list(self.vol.parent.vol.type_name, self.vol.member_name)
999+
1000+
9641001
class files_struct(objects.StructType):
9651002
def get_fds(self) -> interfaces.objects.ObjectInterface:
9661003
if self.has_member("fdt"):

0 commit comments

Comments
 (0)