From 1eacddc79c2975fe1e53167f86bec365c68636b9 Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Mon, 17 Mar 2025 17:45:13 -0500 Subject: [PATCH 1/3] Add needed checks to prevent backtraces in ELF parsing --- .../symbols/linux/extensions/__init__.py | 72 ++++++++++++------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index 2094d63da..524f2a7c6 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -337,39 +337,55 @@ class module(generic.GenericIntelProcess): @property def section_symtab(self): - if self.has_member("kallsyms"): - return self.kallsyms.symtab - elif self.has_member("symtab"): - return self.symtab + try: + if self.has_member("kallsyms"): + return self.kallsyms.symtab + elif self.has_member("symtab"): + return self.symtab + except exceptions.InvalidAddressException: + vollog.debug(f"Page fault encountered when accessing symtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + return None raise AttributeError("Unable to get symtab") @property def num_symtab(self): - if self.has_member("kallsyms"): - return int(self.kallsyms.num_symtab) - elif self.has_member("num_symtab"): - return int(self.member("num_symtab")) + try: + if self.has_member("kallsyms"): + return int(self.kallsyms.num_symtab) + elif self.has_member("num_symtab"): + return int(self.member("num_symtab")) + except exceptions.InvalidAddressException: + vollog.debug(f"Page fault encountered when accessing num_symtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + return None raise AttributeError("Unable to determine number of symbols") @property def section_strtab(self): - # Newer kernels - if self.has_member("kallsyms"): - return self.kallsyms.strtab - # Older kernels - elif self.has_member("strtab"): - return self.strtab + try: + # Newer kernels + if self.has_member("kallsyms"): + return self.kallsyms.strtab + # Older kernels + elif self.has_member("strtab"): + return self.strtab + except exceptions.InvalidAddressException: + vollog.debug(f"Page fault encountered when accessing strtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + return None raise AttributeError("Unable to get strtab") @property def section_typetab(self): - if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"): - # kernels >= 4.5 8244062ef1e54502ef55f54cced659913f244c3e: kallsyms was added - # kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b: types have its own array - return self.kallsyms.typetab + try: + if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"): + # kernels >= 4.5 8244062ef1e54502ef55f54cced659913f244c3e: kallsyms was added + # kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b: types have its own array + return self.kallsyms.typetab + except exceptions.InvalidAddressException: + vollog.debug(f"Page fault encountered when accessing typetab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + return None raise AttributeError("Unable to get typetab section, it needs a kernel >= 5.2") @@ -385,14 +401,18 @@ class module(generic.GenericIntelProcess): Returns: A single-character string representing the symbol type """ - if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"): - # kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b types have its own array - layer = self._context.layers[self.vol.layer_name] - sym_type = layer.read(self.section_typetab + symbol_index, 1) - sym_type = sym_type.decode("utf-8", errors="ignore") - else: - # kernels < 5.2 the type was stored in the st_info - sym_type = chr(symbol.st_info) + try: + if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"): + # kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b types have its own array + layer = self._context.layers[self.vol.layer_name] + sym_type = layer.read(self.section_typetab + symbol_index, 1) + sym_type = sym_type.decode("utf-8", errors="ignore") + else: + # kernels < 5.2 the type was stored in the st_info + sym_type = chr(symbol.st_info) + except exceptions.InvalidAddressException: + vollog.debug(f"Page fault encountered when accessing symbol type of index {symbol_index} of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + return None return sym_type From e48d2972a6e44bb01fc5c2f4eafa28b91d1e4071 Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Mon, 17 Mar 2025 17:46:25 -0500 Subject: [PATCH 2/3] Add needed checks to prevent backtraces in ELF parsing --- .../symbols/linux/extensions/__init__.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index 524f2a7c6..959d33c60 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -343,7 +343,9 @@ class module(generic.GenericIntelProcess): elif self.has_member("symtab"): return self.symtab except exceptions.InvalidAddressException: - vollog.debug(f"Page fault encountered when accessing symtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + vollog.debug( + f"Page fault encountered when accessing symtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}" + ) return None raise AttributeError("Unable to get symtab") @@ -356,7 +358,9 @@ class module(generic.GenericIntelProcess): elif self.has_member("num_symtab"): return int(self.member("num_symtab")) except exceptions.InvalidAddressException: - vollog.debug(f"Page fault encountered when accessing num_symtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + vollog.debug( + f"Page fault encountered when accessing num_symtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}" + ) return None raise AttributeError("Unable to determine number of symbols") @@ -371,7 +375,9 @@ class module(generic.GenericIntelProcess): elif self.has_member("strtab"): return self.strtab except exceptions.InvalidAddressException: - vollog.debug(f"Page fault encountered when accessing strtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + vollog.debug( + f"Page fault encountered when accessing strtab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}" + ) return None raise AttributeError("Unable to get strtab") @@ -384,7 +390,9 @@ class module(generic.GenericIntelProcess): # kernels >= 5.2 1c7651f43777cdd59c1aaa82c87324d3e7438c7b: types have its own array return self.kallsyms.typetab except exceptions.InvalidAddressException: - vollog.debug(f"Page fault encountered when accessing typetab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + vollog.debug( + f"Page fault encountered when accessing typetab of ELF at {self.vol.offset:#x} in {self.vol.layer_name}" + ) return None raise AttributeError("Unable to get typetab section, it needs a kernel >= 5.2") @@ -411,7 +419,9 @@ class module(generic.GenericIntelProcess): # kernels < 5.2 the type was stored in the st_info sym_type = chr(symbol.st_info) except exceptions.InvalidAddressException: - vollog.debug(f"Page fault encountered when accessing symbol type of index {symbol_index} of ELF at {self.vol.offset:#x} in {self.vol.layer_name}") + vollog.debug( + f"Page fault encountered when accessing symbol type of index {symbol_index} of ELF at {self.vol.offset:#x} in {self.vol.layer_name}" + ) return None return sym_type From 07b74fd8e30753612610b712514ca1f5e5a0b93a Mon Sep 17 00:00:00 2001 From: Andrew Case Date: Mon, 17 Mar 2025 18:28:13 -0500 Subject: [PATCH 3/3] Add typing to functions in modules class --- .../symbols/linux/extensions/__init__.py | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index 959d33c60..6767650dc 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -99,13 +99,13 @@ class module(generic.GenericIntelProcess): return self.mem[module_mem_index] - def _get_mem_size(self, mod_mem_type_name): + def _get_mem_size(self, mod_mem_type_name) -> int: return self._get_mem_type(mod_mem_type_name).size - def _get_mem_base(self, mod_mem_type_name): + def _get_mem_base(self, mod_mem_type_name) -> int: return self._get_mem_type(mod_mem_type_name).base - def get_module_base(self): + def get_module_base(self) -> int: if self.has_member("mem"): # kernels 6.4+ return self._get_mem_base("MOD_TEXT") elif self.has_member("core_layout"): @@ -115,7 +115,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to get module base") - def get_init_size(self): + def get_init_size(self) -> int: if self.has_member("mem"): # kernels 6.4+ return ( self._get_mem_size("MOD_INIT_TEXT") @@ -129,7 +129,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to determine .init section size of module") - def get_core_size(self): + def get_core_size(self) -> int: if self.has_member("mem"): # kernels 6.4+ return ( self._get_mem_size("MOD_TEXT") @@ -144,7 +144,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to determine core size of module") - def get_core_text_size(self): + def get_core_text_size(self) -> int: if self.has_member("mem"): # kernels 6.4+ return self._get_mem_size("MOD_TEXT") elif self.has_member("core_layout"): @@ -154,7 +154,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to determine core text size of module") - def get_module_core(self): + def get_module_core(self) -> objects.Pointer: if self.has_member("mem"): # kernels 6.4+ return self._get_mem_base("MOD_TEXT") elif self.has_member("core_layout"): @@ -163,7 +163,7 @@ class module(generic.GenericIntelProcess): return self.module_core raise AttributeError("Unable to get module core") - def get_module_init(self): + def get_module_init(self) -> objects.Pointer: if self.has_member("mem"): # kernels 6.4+ return self._get_mem_base("MOD_INIT_TEXT") elif self.has_member("init_layout"): @@ -172,9 +172,12 @@ class module(generic.GenericIntelProcess): return self.module_init raise AttributeError("Unable to get module init") - def get_name(self): + def get_name(self) -> Optional[str]: """Get the name of the module as a string""" - return utility.array_to_string(self.name) + try: + return utility.array_to_string(self.name) + except exceptions.InvalidAddressException: + return None def _get_sect_count(self, grp: interfaces.objects.ObjectInterface) -> int: """Try to determine the number of valid sections""" @@ -336,7 +339,7 @@ class module(generic.GenericIntelProcess): return None @property - def section_symtab(self): + def section_symtab(self) -> Optional[interfaces.objects.ObjectInterface]: try: if self.has_member("kallsyms"): return self.kallsyms.symtab @@ -351,7 +354,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to get symtab") @property - def num_symtab(self): + def num_symtab(self) -> Optional[int]: try: if self.has_member("kallsyms"): return int(self.kallsyms.num_symtab) @@ -366,7 +369,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to determine number of symbols") @property - def section_strtab(self): + def section_strtab(self) -> Optional[interfaces.objects.ObjectInterface]: try: # Newer kernels if self.has_member("kallsyms"): @@ -383,7 +386,7 @@ class module(generic.GenericIntelProcess): raise AttributeError("Unable to get strtab") @property - def section_typetab(self): + def section_typetab(self) -> Optional[interfaces.objects.ObjectInterface]: try: if self.has_member("kallsyms") and self.kallsyms.has_member("typetab"): # kernels >= 4.5 8244062ef1e54502ef55f54cced659913f244c3e: kallsyms was added @@ -399,7 +402,7 @@ class module(generic.GenericIntelProcess): def get_symbol_type( self, symbol: interfaces.objects.ObjectInterface, symbol_index: int - ) -> str: + ) -> Optional[str]: """Determines the type of a given ELF symbol. Args: