From ebe19bf179068952a612ad94e29d08851b70b429 Mon Sep 17 00:00:00 2001 From: Eve Date: Fri, 10 Nov 2023 20:30:38 +0000 Subject: [PATCH 1/3] Linux: update maple tree extension to fix issue #1032 --- volatility3/framework/symbols/linux/extensions/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index 3fb772135..c3e50fce4 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -301,7 +301,11 @@ class maple_tree(objects.StructType): self.ma_flags & self.MT_FLAGS_HEIGHT_MASK ) >> self.MT_FLAGS_HEIGHT_OFFSET yield from self._parse_maple_tree_node( - self.ma_root, maple_tree_offset, expected_maple_tree_depth + self.ma_root, + maple_tree_offset, + expected_maple_tree_depth, + seen=set(), + current_depth=1, ) def _parse_maple_tree_node( From 7fe086f64f7c98a2c46990eff2e585a383d4bea2 Mon Sep 17 00:00:00 2001 From: Eve Date: Fri, 1 Dec 2023 13:37:09 +0000 Subject: [PATCH 2/3] Linux: update maple tree extension to fix issue #1032 correcting the mutable type used as a default parameter. --- .../symbols/linux/extensions/__init__.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index c3e50fce4..92c544c30 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -301,11 +301,7 @@ class maple_tree(objects.StructType): self.ma_flags & self.MT_FLAGS_HEIGHT_MASK ) >> self.MT_FLAGS_HEIGHT_OFFSET yield from self._parse_maple_tree_node( - self.ma_root, - maple_tree_offset, - expected_maple_tree_depth, - seen=set(), - current_depth=1, + self.ma_root, maple_tree_offset, expected_maple_tree_depth ) def _parse_maple_tree_node( @@ -313,11 +309,16 @@ class maple_tree(objects.StructType): maple_tree_entry, parent, expected_maple_tree_depth, - seen=set(), + seen=None, current_depth=1, ): """Recursively parse Maple Tree Nodes and yield all non empty slots""" + # create seen set if it does not exist, e.g. on the first call into + # this recursive function. + if seen == None: + seen = set() + # protect against unlikely loop if maple_tree_entry in seen: vollog.warning( @@ -326,6 +327,7 @@ class maple_tree(objects.StructType): return else: seen.add(maple_tree_entry) + # check if we have exceeded the expected depth of this maple tree. # e.g. when current_depth is larger than expected_maple_tree_depth there may be an issue. # it is normal that expected_maple_tree_depth is equal to current_depth. @@ -334,6 +336,7 @@ class maple_tree(objects.StructType): f"The depth for the maple tree at {hex(self.vol.offset)} is {expected_maple_tree_depth}, however when parsing the nodes " f"a depth of {current_depth} was reached. This is unexpected and may lead to incorrect results." ) + # parse the mte to extract the pointer value, node type, and leaf status pointer = maple_tree_entry & ~(self.MAPLE_NODE_POINTER_MASK) node_type = ( From 276e695237e0a93cdb4755bcc8c063acda7f3a85 Mon Sep 17 00:00:00 2001 From: Eve Date: Fri, 1 Dec 2023 13:46:00 +0000 Subject: [PATCH 3/3] Linux: update maple tree extension comment around the seen set. --- .../framework/symbols/linux/extensions/__init__.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index 92c544c30..dc31a7628 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -314,8 +314,13 @@ class maple_tree(objects.StructType): ): """Recursively parse Maple Tree Nodes and yield all non empty slots""" - # create seen set if it does not exist, e.g. on the first call into - # this recursive function. + # Create seen set if it does not exist, e.g. on the first call into this recursive function. This + # must be None or an existing set of addresses for MTEs that have already been processed or that + # should otherwise be ignored. If parsing from the root node for example this should be None on the + # first call. If you needed to parse all nodes downwards from part of the tree this should still be + # None. If however you wanted to parse from a node, but ignore some parts of the tree below it then + # this could be populated with the addresses of the nodes you wish to ignore. + if seen == None: seen = set()