Linux: hidden_modules: Add docstrings and comments to enhance the documentation of the module verification process. Move the hardcoded values to the linux constants file.

This commit is contained in:
Gustavo Moreira
2024-10-30 09:56:05 +11:00
parent f537c4a7e0
commit 4b76b699ad
2 changed files with 36 additions and 9 deletions
@@ -339,3 +339,11 @@ class PT_FLAGS(Flag):
def flags(self) -> str:
"""Returns the ptrace flags string"""
return str(self).replace(self.__class__.__name__ + ".", "")
# Valid sizes for modules. Note that the Linux kernel does not define these values; they
# are based on empirical observations of typical memory allocations for kernel modules.
# We use this to verify that the found module falls within reasonable limits.
MODULE_MAXIMUM_CORE_SIZE = 20000000
MODULE_MAXIMUM_CORE_TEXT_SIZE = 20000000
MODULE_MINIMUM_SIZE = 4096
@@ -13,12 +13,24 @@ from typing import Generator, Iterable, Iterator, Optional, Tuple, List, Union,
from volatility3.framework import constants, exceptions, objects, interfaces, symbols
from volatility3.framework.renderers import conversion
from volatility3.framework.constants.linux import SOCK_TYPES, SOCK_FAMILY
from volatility3.framework.constants.linux import IP_PROTOCOLS, IPV6_PROTOCOLS
from volatility3.framework.constants.linux import TCP_STATES, NETLINK_PROTOCOLS
from volatility3.framework.constants.linux import ETH_PROTOCOLS, BLUETOOTH_STATES
from volatility3.framework.constants.linux import BLUETOOTH_PROTOCOLS, SOCKET_STATES
from volatility3.framework.constants.linux import CAPABILITIES, PT_FLAGS
from volatility3.framework.constants.linux import (
SOCK_TYPES,
SOCK_FAMILY,
IP_PROTOCOLS,
IPV6_PROTOCOLS,
TCP_STATES,
NETLINK_PROTOCOLS,
ETH_PROTOCOLS,
BLUETOOTH_STATES,
BLUETOOTH_PROTOCOLS,
SOCKET_STATES,
CAPABILITIES,
PT_FLAGS,
MODULE_MAXIMUM_CORE_SIZE,
MODULE_MAXIMUM_CORE_TEXT_SIZE,
MODULE_MINIMUM_SIZE,
)
from volatility3.framework.layers import linear
from volatility3.framework.objects import utility
from volatility3.framework.symbols import generic, linux, intermed
@@ -36,16 +48,23 @@ class module(generic.GenericIntelProcess):
self._mod_mem_type = None # Initialize _mod_mem_type to None for memoization
def is_valid(self):
"""Determine whether it is a valid module object by verifying the self-referential
in module_kobject. This also confirms that the module is actively allocated and
not a remnant of freed memory or a failed module load attempt by verifying the
module memory section sizes.
"""
layer = self._context.layers[self.vol.layer_name]
# Make sure the entire module content is readable
if not layer.is_valid(self.vol.offset, self.vol.size):
return False
core_size = self.get_core_size()
core_text_size = self.get_core_text_size()
init_size = self.get_init_size()
if not (
1 <= core_size <= 20000000
and core_size + self.get_init_size() >= 4096
and 1 <= self.get_core_text_size() <= 20000000
0 < core_text_size <= MODULE_MAXIMUM_CORE_TEXT_SIZE
and 0 < core_size <= MODULE_MAXIMUM_CORE_SIZE
and core_size + init_size >= MODULE_MINIMUM_SIZE
):
return False