Skip to content

Commit ba64379

Browse files
ebpf: new way of compiling the modules
- Don't rename libbpf's bpf_map_def struct, and distribute the needed bpf headers. The bpf_map_def struct has been deprecated for quite some time now, and it was been removed on >= 6.2 anyway. We still need it, because we use gobpf. - Improved compilation behaviour: - We don't require the kernel sources anymore. We can just use the kernel headers from the distribution. - There's no need to copy the sources to the kernel tree, the modules can be compiled from the ebpf_prog/ dir. - Compiling against kernels 6.x seems to solve the problem we had with VPNs, where connections were not intercepted with modules compiled against 5.8, on kernels >= 5.19. The modules has been tested on kernels 4.17, 5.4, 5.10, 5.15, 6.1 and 6.2 (kernel connections included). Closes: #939
1 parent 9d35310 commit ba64379

File tree

11 files changed

+6038
-219
lines changed

11 files changed

+6038
-219
lines changed

.github/workflows/build_ebpf_modules.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ jobs:
2424
# The matrix configuration will execute the steps, once per dimension defined:
2525
# kernel 5.8 + tag 1.5.0
2626
# kernel 5.8 + tag master
27-
# kernel 5.19 + tag 1.5.0, etc
27+
# kernel 6.0 + tag 1.5.0, etc
2828
build:
2929
strategy:
3030
matrix:
31-
kernel: ["5.8", "5.19"]
31+
kernel: ["5.8", "6.0"]
3232
tag: ["1.5.0", "master"]
3333

3434
runs-on: ubuntu-20.04

ebpf_prog/Makefile

Lines changed: 55 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,57 @@
1-
#taken from /samples/bpf/Makefile and removed all targets
2-
3-
# SPDX-License-Identifier: GPL-2.0
4-
5-
BPF_SAMPLES_PATH ?= $(abspath $(srctree)/$(src))
6-
TOOLS_PATH := $(BPF_SAMPLES_PATH)/../../tools
7-
8-
# Libbpf dependencies
9-
LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
10-
11-
CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o
12-
TRACE_HELPERS := ../../tools/testing/selftests/bpf/trace_helpers.o
13-
14-
always-y += opensnitch.o opensnitch-dns.o opensnitch-procs.o
15-
16-
ifeq ($(ARCH), arm)
17-
# Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux
18-
# headers when arm instruction set identification is requested.
19-
ARM_ARCH_SELECTOR := $(filter -D__LINUX_ARM_ARCH__%, $(KBUILD_CFLAGS))
20-
BPF_EXTRA_CFLAGS := $(ARM_ARCH_SELECTOR)
21-
TPROGS_CFLAGS += $(ARM_ARCH_SELECTOR)
22-
endif
23-
24-
TPROGS_CFLAGS += -Wall -O2
25-
TPROGS_CFLAGS += -Wmissing-prototypes
26-
TPROGS_CFLAGS += -Wstrict-prototypes
27-
28-
TPROGS_CFLAGS += -I$(objtree)/usr/include
29-
TPROGS_CFLAGS += -I$(srctree)/tools/testing/selftests/bpf/
30-
TPROGS_CFLAGS += -I$(srctree)/tools/lib/
31-
TPROGS_CFLAGS += -I$(srctree)/tools/include
32-
TPROGS_CFLAGS += -I$(srctree)/tools/perf
33-
TPROGS_CFLAGS += -DHAVE_ATTR_TEST=0
34-
35-
ifdef SYSROOT
36-
TPROGS_CFLAGS += --sysroot=$(SYSROOT)
37-
TPROGS_LDFLAGS := -L$(SYSROOT)/usr/lib
38-
endif
39-
40-
TPROGCFLAGS_bpf_load.o += -Wno-unused-variable
41-
42-
TPROGS_LDLIBS += $(LIBBPF) -lelf -lz
43-
TPROGLDLIBS_tracex4 += -lrt
44-
TPROGLDLIBS_trace_output += -lrt
45-
TPROGLDLIBS_map_perf_test += -lrt
46-
TPROGLDLIBS_test_overhead += -lrt
47-
TPROGLDLIBS_xdpsock += -pthread
48-
49-
# Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline:
50-
# make M=samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
51-
LLC ?= llc
1+
# OpenSnitch - 2023
2+
#
3+
# On Debian based distros we need the following 2 directories.
4+
# Otherwise, just use the kernel headers from the kernel sources.
5+
#
6+
KERNEL_DIR ?= /lib/modules/$(shell uname -r)/source
7+
KERNEL_HEADERS ?= /usr/src/linux-headers-$(shell uname -r)/
528
CLANG ?= clang
53-
LLVM_OBJCOPY ?= llvm-objcopy
54-
BTF_PAHOLE ?= pahole
55-
56-
# Detect that we're cross compiling and use the cross compiler
57-
ifdef CROSS_COMPILE
58-
CLANG_ARCH_ARGS = --target=$(notdir $(CROSS_COMPILE:%-=%))
59-
endif
60-
61-
# Don't evaluate probes and warnings if we need to run make recursively
62-
ifneq ($(src),)
63-
HDR_PROBE := $(shell printf "\#include <linux/types.h>\n struct list_head { int a; }; int main() { return 0; }" | \
64-
$(CC) $(TPROGS_CFLAGS) $(TPROGS_LDFLAGS) -x c - \
65-
-o /dev/null 2>/dev/null && echo okay)
66-
67-
ifeq ($(HDR_PROBE),)
68-
$(warning WARNING: Detected possible issues with include path.)
69-
$(warning WARNING: Please install kernel headers locally (make headers_install).)
70-
endif
71-
72-
BTF_LLC_PROBE := $(shell $(LLC) -march=bpf -mattr=help 2>&1 | grep dwarfris)
73-
BTF_PAHOLE_PROBE := $(shell $(BTF_PAHOLE) --help 2>&1 | grep BTF)
74-
BTF_OBJCOPY_PROBE := $(shell $(LLVM_OBJCOPY) --help 2>&1 | grep -i 'usage.*llvm')
75-
BTF_LLVM_PROBE := $(shell echo "int main() { return 0; }" | \
76-
$(CLANG) -target bpf -O2 -g -c -x c - -o ./llvm_btf_verify.o; \
77-
readelf -S ./llvm_btf_verify.o | grep BTF; \
78-
/bin/rm -f ./llvm_btf_verify.o)
79-
80-
BPF_EXTRA_CFLAGS += -fno-stack-protector
81-
ifneq ($(BTF_LLVM_PROBE),)
82-
BPF_EXTRA_CFLAGS += -g
83-
else
84-
ifneq ($(and $(BTF_LLC_PROBE),$(BTF_PAHOLE_PROBE),$(BTF_OBJCOPY_PROBE)),)
85-
BPF_EXTRA_CFLAGS += -g
86-
LLC_FLAGS += -mattr=dwarfris
87-
DWARF2BTF = y
88-
endif
89-
endif
90-
endif
91-
92-
# Trick to allow make to be run from this directory
93-
all:
94-
$(MAKE) -C ../../ M=$(CURDIR) BPF_SAMPLES_PATH=$(CURDIR)
95-
9+
LLC ?= llc
10+
LLVM_STRIP ?= llvm-strip -g
11+
ARCH ?= $(shell arch)
12+
13+
# as in /usr/src/linux-headers-*/arch/
14+
# TODO: extract correctly the archs, and add more if needed.
15+
ifeq ($(ARCH),x86_64)
16+
ARCH := x86
17+
else ifeq ($(ARCH),i686)
18+
ARCH := x86
19+
else ifeq ($(ARCH),armv7l)
20+
ARCH := arm
21+
else ifeq ($(ARCH),aarch64)
22+
ARCH := arm64
23+
endif
24+
25+
ifeq ($(ARCH),arm)
26+
# on previous archs, it fails with "SMP not supported on pre-ARMv6"
27+
EXTRA_FLAGS = "-D__LINUX_ARM_ARCH__=7"
28+
endif
29+
30+
BIN := opensnitch.o opensnitch-procs.o opensnitch-dns.o
31+
CLANG_FLAGS = -I. \
32+
-I$(KERNEL_HEADERS)/arch/x86/include/generated/ \
33+
-I$(KERNEL_HEADERS)/include \
34+
-include $(KERNEL_DIR)/include/linux/kconfig.h \
35+
-I$(KERNEL_DIR)/include \
36+
-I$(KERNEL_DIR)/include/uapi \
37+
-I$(KERNEL_DIR)/include/generated/uapi \
38+
-I$(KERNEL_DIR)/arch/$(ARCH)/include \
39+
-I$(KERNEL_DIR)/arch/$(ARCH)/include/generated \
40+
-I$(KERNEL_DIR)/arch/$(ARCH)/include/uapi \
41+
-I$(KERNEL_DIR)/arch/$(ARCH)/include/generated/uapi \
42+
-I$(KERNEL_DIR)/tools/testing/selftests/bpf/ \
43+
-D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \
44+
-D__TARGET_ARCH_$(ARCH) -Wno-compare-distinct-pointer-types \
45+
$(EXTRA_FLAGS) \
46+
-Wno-gnu-variable-sized-type-not-at-end \
47+
-Wno-address-of-packed-member -Wno-tautological-compare \
48+
-Wno-unknown-warning-option \
49+
-g -O2 -emit-llvm
50+
51+
all: $(BIN)
52+
53+
%.o: %.c
54+
$(CLANG) $(CLANG_FLAGS) -c $< -o - | \
55+
$(LLC) -march=bpf -mcpu=$(CPU) -filetype=obj -o $@
9656
clean:
97-
$(MAKE) -C ../../ M=$(CURDIR) clean
98-
@find $(CURDIR) -type f -name '*~' -delete
99-
100-
$(LIBBPF): FORCE
101-
# Fix up variables inherited from Kbuild that tools/ build system won't like
102-
$(MAKE) -C $(dir $@) RM='rm -rf' EXTRA_CFLAGS="$(TPROGS_CFLAGS)" \
103-
LDFLAGS=$(TPROGS_LDFLAGS) srctree=$(BPF_SAMPLES_PATH)/../../ O=
104-
105-
$(obj)/syscall_nrs.h: $(obj)/syscall_nrs.s FORCE
106-
$(call filechk,offsets,__SYSCALL_NRS_H__)
107-
108-
targets += syscall_nrs.s
109-
clean-files += syscall_nrs.h
110-
111-
FORCE:
112-
113-
114-
# Verify LLVM compiler tools are available and bpf target is supported by llc
115-
.PHONY: verify_cmds verify_target_bpf $(CLANG) $(LLC)
116-
117-
verify_cmds: $(CLANG) $(LLC)
118-
@for TOOL in $^ ; do \
119-
if ! (which -- "$${TOOL}" > /dev/null 2>&1); then \
120-
echo "*** ERROR: Cannot find LLVM tool $${TOOL}" ;\
121-
exit 1; \
122-
else true; fi; \
123-
done
124-
125-
verify_target_bpf: verify_cmds
126-
@if ! (${LLC} -march=bpf -mattr=help > /dev/null 2>&1); then \
127-
echo "*** ERROR: LLVM (${LLC}) does not support 'bpf' target" ;\
128-
echo " NOTICE: LLVM version >= 3.7.1 required" ;\
129-
exit 2; \
130-
else true; fi
131-
132-
$(BPF_SAMPLES_PATH)/*.c: verify_target_bpf $(LIBBPF)
133-
$(src)/*.c: verify_target_bpf $(LIBBPF)
134-
135-
$(obj)/tracex5_kern.o: $(obj)/syscall_nrs.h
136-
$(obj)/hbm_out_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
137-
$(obj)/hbm.o: $(src)/hbm.h
138-
$(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h
139-
140-
-include $(BPF_SAMPLES_PATH)/Makefile.target
141-
142-
# asm/sysreg.h - inline assembly used by it is incompatible with llvm.
143-
# But, there is no easy way to fix it, so just exclude it since it is
144-
# useless for BPF samples.
145-
$(obj)/%.o: $(src)/%.c
146-
@echo " CLANG-bpf " $@
147-
$(Q)$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(BPF_EXTRA_CFLAGS) \
148-
-I$(obj) -I$(srctree)/tools/testing/selftests/bpf/ \
149-
-I$(srctree)/tools/lib/ \
150-
-D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \
151-
-D__TARGET_ARCH_$(SRCARCH) -Wno-compare-distinct-pointer-types \
152-
-Wno-gnu-variable-sized-type-not-at-end \
153-
-Wno-address-of-packed-member -Wno-tautological-compare \
154-
-Wno-unknown-warning-option $(CLANG_ARCH_ARGS) \
155-
-I$(srctree)/samples/bpf/ -include asm_goto_workaround.h \
156-
-O2 -emit-llvm -c $< -o -| $(LLC) -march=bpf $(LLC_FLAGS) -filetype=obj -o $@
157-
ifeq ($(DWARF2BTF),y)
158-
$(BTF_PAHOLE) -J $@
159-
endif
57+
rm -f *.o

ebpf_prog/README

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Compilation requires getting kernel sources.
1+
Compilation requires getting kernel sources for now.
22

33
There's a helper script to automate this process:
44
https://github.com/evilsocket/opensnitch/blob/master/utils/packaging/build_modules.sh
@@ -9,24 +9,36 @@ The basic steps to compile the modules are:
99
cd opensnitch
1010
wget https://github.com/torvalds/linux/archive/v5.8.tar.gz
1111
tar -xf v5.8.tar.gz
12-
patch linux-5.8/tools/lib/bpf/bpf_helpers.h < ebpf_prog/file.patch
13-
cp ebpf_prog/opensnitch*.c ebpf_prog/common.h ebpf_prog/Makefile linux-5.8/samples/bpf
12+
cp ebpf_prog/opensnitch*.c ebpf_prog/common* ebpf_prog/Makefile linux-5.8/samples/bpf/
13+
cp -r ebpf_prog/bpf_headers/ linux-5.8/samples/bpf/
1414
cd linux-5.8 && yes "" | make oldconfig && make prepare && make headers_install # (1 min)
15-
cd samples/bpf && make
16-
objdump -h opensnitch.o #you should see many section, number 1 should be called kprobe/tcp_v4_connect
17-
llvm-strip -g opensnitch.o #remove debug info
18-
sudo cp opensnitch*.o /etc/opensnitchd/
15+
cd samples/bpf && make KERNEL_DIR=../../linux-5.8/
16+
objdump -h opensnitch.o # you should see many sections, number 1 should be called kprobe/tcp_v4_connect
17+
llvm-strip -g opensnitch*.o # remove debug info
18+
sudo cp opensnitch*.o /usr/lib/opensnitchd/ebpf/ # or /etc/opensnitchd for < v1.6.x
1919
cd ../../../daemon
2020

21-
opensnitchd expects to find opensnitch.o in:
21+
Since v1.6.0, opensnitchd expects to find the opensnitch*.o modules under:
2222
/usr/local/lib/opensnitchd/ebpf/
2323
/usr/lib/opensnitchd/ebpf/
24-
/etc/opensnitchd/ # deprecated
24+
/etc/opensnitchd/ # deprecated, only on < v1.5.x
2525

2626
start opensnitchd with:
2727

2828
opensnitchd -rules-path /etc/opensnitchd/rules -process-monitor-method ebpf
2929

30+
---
31+
32+
### Compiling for Fedora (and others rpm based systems)
33+
34+
You need to install the kernel-devel, clang and llvm packages.
35+
36+
Then: `cd ebpf_prog/ ; make KERNEL_DIR=/usr/src/kernels/$(uname -r)/`
37+
38+
(or just pass the kernel version you want)
39+
40+
### Notes
41+
3042
The kernel where you intend to run it must have some options activated:
3143

3244
$ grep BPF /boot/config-$(uname -r)
@@ -42,11 +54,19 @@ For the opensnitch-procs.o module to work, this option must be enabled:
4254
$ grep FTRACE_SYSCALLS /boot/config-$(uname -r)
4355
CONFIG_FTRACE_SYSCALLS=y
4456

45-
Also, in some distributions debugfs is not mounted automatically, so you need
46-
to do it manually:
57+
(https://github.com/iovisor/bcc/blob/master/docs/kernel_config.md)
58+
59+
Also, in some distributions debugfs is not mounted automatically.
60+
Since v1.6.0 we try to mount it automatically. If you're running
61+
a lower version so you'll need to mount it manually:
4762

4863
$ sudo mount -t debugfs none /sys/kernel/debug
4964

5065
In order to make it permanent add it to /etc/fstab:
5166

5267
debugfs /sys/kernel/debug debugfs defaults 0 0
68+
69+
70+
opensnitch-procs.o and opensnitch-dns.o are only compatible with kernels >= 5.5,
71+
bpf_probe_read_user*() were added on that kernel on:
72+
https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md#helpers

0 commit comments

Comments
 (0)