From 200099f8b3f92e2ad228e0a481a835f1fbc9d8b6 Mon Sep 17 00:00:00 2001 From: Gustavo Moreira Date: Mon, 8 May 2023 14:58:51 +0200 Subject: [PATCH] Improve support for socket filters in kernels < 4.1.52 --- .../framework/plugins/linux/sockstat.py | 23 +++++++++++++++---- .../framework/symbols/linux/__init__.py | 1 + .../symbols/linux/extensions/__init__.py | 17 ++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/volatility3/framework/plugins/linux/sockstat.py b/volatility3/framework/plugins/linux/sockstat.py index 72a1e453e..f06b3ad8e 100644 --- a/volatility3/framework/plugins/linux/sockstat.py +++ b/volatility3/framework/plugins/linux/sockstat.py @@ -150,19 +150,32 @@ class SockHandlers(interfaces.configuration.VersionableInterface): return bpfprog = sock_filter.prog - if bpfprog.type == 0: - # BPF_PROG_TYPE_UNSPEC = 0 + + BPF_PROG_TYPE_UNSPEC = 0 # cBPF filter + try: + bpfprog_type = bpfprog.get_type() + if bpfprog_type == BPF_PROG_TYPE_UNSPEC: + return # cBPF filter + except AttributeError: + # kernel < 3.18.140, it's a cBPF filter + return + + BPF_PROG_TYPE_SOCKET_FILTER = 1 # eBPF filter + if bpfprog_type != BPF_PROG_TYPE_SOCKET_FILTER: + socket_filter["bpf_filter_type"] = f"UNK({bpfprog_type})" + vollog.warning(f"Unexpected BPF type {bpfprog_type} for a socket") return socket_filter["bpf_filter_type"] = "eBPF" if not bpfprog.has_member("aux") or not bpfprog.aux: - return + return # kernel < 3.18.140 bpfprog_aux = bpfprog.aux + if bpfprog_aux.has_member("id"): - # `id` member was added to `bpf_prog_aux` in kernels 4.13 + # `id` member was added to `bpf_prog_aux` in kernels 4.13.16 socket_filter["bpf_filter_id"] = str(bpfprog_aux.id) if bpfprog_aux.has_member("name"): - # `name` was added to `bpf_prog_aux` in kernels 4.15 + # `name` was added to `bpf_prog_aux` in kernels 4.15.18 bpfprog_name = utility.array_to_string(bpfprog_aux.name) if bpfprog_name: socket_filter["bpf_filter_name"] = bpfprog_name diff --git a/volatility3/framework/symbols/linux/__init__.py b/volatility3/framework/symbols/linux/__init__.py index 858845125..3780a86f0 100644 --- a/volatility3/framework/symbols/linux/__init__.py +++ b/volatility3/framework/symbols/linux/__init__.py @@ -30,6 +30,7 @@ class LinuxKernelIntermedSymbols(intermed.IntermediateSymbolTable): self.set_type_class("kobject", extensions.kobject) # Might not exist in the current symbols self.optional_set_type_class("module", extensions.module) + self.optional_set_type_class("bpf_prog", extensions.bpf_prog) # Mount self.set_type_class("vfsmount", extensions.vfsmount) diff --git a/volatility3/framework/symbols/linux/extensions/__init__.py b/volatility3/framework/symbols/linux/extensions/__init__.py index 3dbf560c6..87bd76554 100644 --- a/volatility3/framework/symbols/linux/extensions/__init__.py +++ b/volatility3/framework/symbols/linux/extensions/__init__.py @@ -1313,3 +1313,20 @@ class xdp_sock(objects.StructType): def get_state(self): # xdp_sock.state is an enum return self.state.lookup() + + +class bpf_prog(objects.StructType): + def get_type(self): + # The program type was in `bpf_prog_aux::prog_type` from 3.18.140 to + # 4.1.52 before it was moved to `bpf_prog::type` + if self.has_member("type"): + # kernel >= 4.1.52 + return self.type + + if self.has_member("aux") and self.aux: + if self.aux.has_member("prog_type"): + # 3.18.140 <= kernel < 4.1.52 + return self.aux.prog_type + + # kernel < 3.18.140 + raise AttributeError("Unable to find the BPF type")