Improve support for socket filters in kernels < 4.1.52

This commit is contained in:
Gustavo Moreira
2023-05-08 14:58:51 +02:00
parent ced6ff346c
commit 200099f8b3
3 changed files with 36 additions and 5 deletions
@@ -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
@@ -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)
@@ -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")