diff --git a/volatility3/framework/objects/__init__.py b/volatility3/framework/objects/__init__.py index 316a30becd..328d92a4d0 100644 --- a/volatility3/framework/objects/__init__.py +++ b/volatility3/framework/objects/__init__.py @@ -445,6 +445,16 @@ def is_readable(self, layer_name: Optional[str] = None) -> bool: layer_name = layer_name or self.vol.native_layer_name return self._context.layers[layer_name].is_valid(self, self.vol.subtype.size) + def __bool__(self): + """Enables checking if a pointer is valid in its memory layer when its evaluated + in a boolean context, for instance: + if not ptr: + continue + Without this method, the code above will only abort if 'ptr = 0', leaving the + code vulnerable to smear memory. + """ + return self.is_readable() + def __getattr__(self, attr: str) -> Any: """Convenience function to access unknown attributes by getting them from the subtype object.""" diff --git a/volatility3/framework/plugins/linux/pidhashtable.py b/volatility3/framework/plugins/linux/pidhashtable.py index 3223aed4a3..374701b8a7 100644 --- a/volatility3/framework/plugins/linux/pidhashtable.py +++ b/volatility3/framework/plugins/linux/pidhashtable.py @@ -20,7 +20,7 @@ class PIDHashTable(plugins.PluginInterface): _required_framework_version = (2, 0, 0) - _version = (1, 0, 0) + _version = (1, 0, 1) @classmethod def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]: @@ -45,9 +45,7 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface] ] def _is_valid_task(self, task) -> bool: - vmlinux = self.context.modules[self.config["kernel"]] - vmlinux_layer = self.context.layers[vmlinux.layer_name] - return bool(task and task.pid > 0 and vmlinux_layer.is_valid(task.parent)) + return bool(task and task.pid > 0 and task.parent) def _get_pidtype_pid(self): vmlinux = self.context.modules[self.config["kernel"]] @@ -88,15 +86,14 @@ def _get_pidhash_array(self): def _walk_upid(self, seen_upids, upid): vmlinux = self.context.modules[self.config["kernel"]] - vmlinux_layer = self.context.layers[vmlinux.layer_name] - while upid and vmlinux_layer.is_valid(upid.vol.offset): + while upid: if upid.vol.offset in seen_upids: break seen_upids.add(upid.vol.offset) pid_chain = upid.pid_chain - if not (pid_chain and vmlinux_layer.is_valid(pid_chain.vol.offset)): + if not pid_chain: break upid = linux.LinuxUtilities.container_of( @@ -105,7 +102,6 @@ def _walk_upid(self, seen_upids, upid): def _get_upids(self): vmlinux = self.context.modules[self.config["kernel"]] - vmlinux_layer = self.context.layers[vmlinux.layer_name] # 2.6.24 <= kernels < 4.15 pidhash = self._get_pidhash_array() @@ -115,7 +111,7 @@ def _get_upids(self): # each entry in the hlist is a upid which is wrapped in a pid ent = hlist.first - while ent and vmlinux_layer.is_valid(ent.vol.offset): + while ent: # upid->pid_chain exists 2.6.24 <= kernel < 4.15 upid = linux.LinuxUtilities.container_of( ent.vol.offset, "upid", "pid_chain", vmlinux