From 6ff31670ed7d5700f533806f7df1970f6e3d3398 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 6 Mar 2024 10:00:29 +0100 Subject: [PATCH 1/3] new(driver/bpf): added bpf configure system similar to the kmod one. Then, added fix for rss_stat becoming an array in kernel 6.2. Signed-off-by: Federico Di Pierro --- driver/Makefile.in | 2 +- driver/bpf/CMakeLists.txt | 19 +++++++++ driver/bpf/Makefile | 21 ++++++++++ driver/bpf/configure/Makefile | 45 +++++++++++++++++++++ driver/bpf/configure/Makefile.inc.in | 13 ++++++ driver/bpf/configure/RSS_STAT_ARRAY/test.c | 46 ++++++++++++++++++++++ driver/bpf/configure/build.sh | 13 ++++++ driver/bpf/fillers.h | 7 ++-- driver/configure/Makefile.inc.in | 6 +-- 9 files changed, 164 insertions(+), 8 deletions(-) create mode 100644 driver/bpf/configure/Makefile create mode 100644 driver/bpf/configure/Makefile.inc.in create mode 100644 driver/bpf/configure/RSS_STAT_ARRAY/test.c create mode 100755 driver/bpf/configure/build.sh diff --git a/driver/Makefile.in b/driver/Makefile.in index 9484435461..7b1fdc2dba 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -40,7 +40,7 @@ ifeq ($(FIRST_MAKEFILE_DIRNAME)/$(FIRST_MAKEFILE_FILENAME), scripts/Makefile.bui # Build phase MODULE_MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) MAKEFILE_INC_FILES := $(shell find $(MODULE_MAKEFILE_DIR)/configure -type f -name Makefile.inc) -$(info [configure] Including $(MAKEFILE_INC_FILES)) +$(info [configure-kmod] Including $(MAKEFILE_INC_FILES)) include $(MAKEFILE_INC_FILES) endif endif # $(strip $(MAKEFILE_LIST)),Makefile diff --git a/driver/bpf/CMakeLists.txt b/driver/bpf/CMakeLists.txt index db29f10b10..8fd0353cc4 100644 --- a/driver/bpf/CMakeLists.txt +++ b/driver/bpf/CMakeLists.txt @@ -55,6 +55,25 @@ foreach(SOURCE IN LISTS BPF_SOURCES) list(APPEND INSTALL_SET ${CMAKE_CURRENT_BINARY_DIR}/src/${FILENAME}) endforeach() +# +# Copy all the "configure" modules +# +file(GLOB configure_modules "${CMAKE_CURRENT_SOURCE_DIR}/configure/*") +foreach(subdir ${configure_modules}) + if(IS_DIRECTORY "${subdir}") + file(RELATIVE_PATH CONFIGURE_MODULE "${CMAKE_CURRENT_SOURCE_DIR}/configure" "${subdir}") + configure_file(configure/${CONFIGURE_MODULE}/test.c src/configure/${CONFIGURE_MODULE}/test.c COPYONLY) + configure_file(configure/Makefile src/configure/${CONFIGURE_MODULE}/Makefile COPYONLY) + configure_file(configure/build.sh src/configure/${CONFIGURE_MODULE}/build.sh COPYONLY) + configure_file(configure/Makefile.inc.in src/configure/${CONFIGURE_MODULE}/Makefile.inc) + list(APPEND INSTALL_SET + "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/build.sh" + "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/test.c" + "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/Makefile" + "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/Makefile.inc") + endif() +endforeach() + if(NOT DEFINED DRIVER_BPF_COMPONENT_NAME) set(DRIVER_BPF_COMPONENT_NAME ${DRIVER_COMPONENT_NAME}) endif() diff --git a/driver/bpf/Makefile b/driver/bpf/Makefile index b43f6b9ec1..9b6a2ee39f 100644 --- a/driver/bpf/Makefile +++ b/driver/bpf/Makefile @@ -13,6 +13,8 @@ always = $(always-y) LLC ?= llc CLANG ?= clang +ifeq ($(strip $(MAKEFILE_LIST)),Makefile) + KERNELDIR ?= /lib/modules/$(shell uname -r)/build # DEBUG = -DBPF_DEBUG @@ -42,6 +44,23 @@ clean: $(MAKE) -C $(KERNELDIR) M=$$PWD clean @rm -f *~ +else + +KERNELDIR ?= $(CURDIR) +# +# Get the path of the module sources +# +FIRST_MAKEFILE := $(firstword $(MAKEFILE_LIST)) +FIRST_MAKEFILE_FILENAME := $(notdir $(FIRST_MAKEFILE)) +FIRST_MAKEFILE_DIRNAME := $(shell basename $(dir $(FIRST_MAKEFILE))) +ifeq ($(FIRST_MAKEFILE_DIRNAME)/$(FIRST_MAKEFILE_FILENAME), scripts/Makefile.build) +# Build phase +MODULE_MAKEFILE_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) +MAKEFILE_INC_FILES := $(shell find $(MODULE_MAKEFILE_DIR)/configure -type f -name Makefile.inc) +$(info [configure-bpf] Including $(MAKEFILE_INC_FILES)) +include $(MAKEFILE_INC_FILES) +endif + $(obj)/probe.o: $(src)/probe.c \ $(src)/bpf_helpers.h \ $(src)/filler_helpers.h \ @@ -66,3 +85,5 @@ $(obj)/probe.o: $(src)/probe.c \ -Wno-unknown-attributes \ -O2 -g -emit-llvm -c $< -o $(patsubst %.o,%.ll,$@) $(LLC) -march=bpf -filetype=obj -o $@ $(patsubst %.o,%.ll,$@) + +endif # $(strip $(MAKEFILE_LIST)),Makefile \ No newline at end of file diff --git a/driver/bpf/configure/Makefile b/driver/bpf/configure/Makefile new file mode 100644 index 0000000000..9e060a3153 --- /dev/null +++ b/driver/bpf/configure/Makefile @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-only OR MIT +# +# Copyright (C) 2023 The Falco Authors. +# +# This file is dual licensed under either the MIT or GPL 2. See +# MIT.txt or GPL.txt for full copies of the license. +# + +always-y += test.o +# kept for compatibility with kernels < 5.11 +always = $(always-y) + +LLC ?= llc +CLANG ?= clang + +KERNELDIR ?= /lib/modules/$(shell uname -r)/build + +# -fmacro-prefix-map is not supported on version of clang older than 10 +# so remove it if necessary. +IS_CLANG_OLDER_THAN_10 := $(shell expr `$(CLANG) -dumpversion | cut -f1 -d.` \<= 10) +ifeq ($(IS_CLANG_OLDER_THAN_10), 1) + KBUILD_CPPFLAGS := $(filter-out -fmacro-prefix-map=%,$(KBUILD_CPPFLAGS)) +endif + +all: + $(MAKE) -C $(KERNELDIR) M=$$PWD + +clean: + $(MAKE) -C $(KERNELDIR) M=$$PWD clean + @rm -f *~ + +$(obj)/test.o: $(src)/test.c + $(CLANG) $(LINUXINCLUDE) \ + $(KBUILD_CPPFLAGS) \ + $(KBUILD_EXTRA_CPPFLAGS) \ + -D__KERNEL__ \ + -D__BPF_TRACING__ \ + -Wno-gnu-variable-sized-type-not-at-end \ + -Wno-address-of-packed-member \ + -fno-jump-tables \ + -fno-stack-protector \ + -Wno-tautological-compare \ + -Wno-unknown-attributes \ + -O2 -g -emit-llvm -c $< -o $(patsubst %.o,%.ll,$@) + $(LLC) -march=bpf -filetype=obj -o $@ $(patsubst %.o,%.ll,$@) diff --git a/driver/bpf/configure/Makefile.inc.in b/driver/bpf/configure/Makefile.inc.in new file mode 100644 index 0000000000..e16040514e --- /dev/null +++ b/driver/bpf/configure/Makefile.inc.in @@ -0,0 +1,13 @@ +MODULE_MAKEFILE_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) + +# Run the module build.sh (wrapper for make) script with an empty environment, but PATH +HAS_@CONFIGURE_MODULE@ := $(shell env -i PATH="$(PATH)" KERNELDIR="$(KERNELDIR)" sh $(MODULE_MAKEFILE_DIR)/build.sh ; echo $$?) + +ifeq ($(HAS_@CONFIGURE_MODULE@),0) +$(info [configure-bpf] Setting HAS_@CONFIGURE_MODULE@ flag) +KBUILD_CPPFLAGS += -DHAS_@CONFIGURE_MODULE@ +else +HAS_@CONFIGURE_MODULE@_OUT := $(shell cat $(MODULE_MAKEFILE_DIR)/build.log) +$(info [configure-bpf] Build output for HAS_@CONFIGURE_MODULE@:) +$(info [configure-bpf] $(HAS_@CONFIGURE_MODULE@_OUT)) +endif diff --git a/driver/bpf/configure/RSS_STAT_ARRAY/test.c b/driver/bpf/configure/RSS_STAT_ARRAY/test.c new file mode 100644 index 0000000000..8ba3f65b43 --- /dev/null +++ b/driver/bpf/configure/RSS_STAT_ARRAY/test.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + +Copyright (C) 2023 The Falco Authors. + +This file is dual licensed under either the MIT or GPL 2. See MIT.txt +or GPL2.txt for full copies of the license. + +*/ + +/* + * Check that mm_struct's field `rss_stat` is an array. + * See 6.2 kernel commit: https://github.com/torvalds/linux/commit/f1a7941243c102a44e8847e3b94ff4ff3ec56f25 + */ + +#include "../../quirks.h" + +#include + +#include "../../ppm_events_public.h" +#include "../../bpf_helpers.h" +#include "../../types.h" +#include "../../maps.h" + +// struct mm_struct declaration +#include + +#ifdef BPF_SUPPORTS_RAW_TRACEPOINTS +#define BPF_PROBE(prefix, event, type) \ +__bpf_section(TP_NAME #event) \ +int bpf_##event(struct type *ctx) +#else +#define BPF_PROBE(prefix, event, type) \ +__bpf_section(TP_NAME prefix #event) \ +int bpf_##event(struct type *ctx) +#endif + +BPF_PROBE("signal/", signal_deliver, signal_deliver_args) +{ + long val; + struct mm_struct *mm; + val = mm->rss_stat[0].count; + return 0; +} + +char __license[] __bpf_section("license") = "Dual MIT/GPL"; diff --git a/driver/bpf/configure/build.sh b/driver/bpf/configure/build.sh new file mode 100755 index 0000000000..4601ec19c6 --- /dev/null +++ b/driver/bpf/configure/build.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# +# Copyright (C) 2023 The Falco Authors. +# +# This file is dual licensed under either the MIT or GPL 2. See +# MIT.txt or GPL.txt for full copies of the license. +# + +SCRIPT=$(readlink -f "$0") +SCRIPT_DIR=$(dirname ${SCRIPT}) + +make -C ${SCRIPT_DIR} > ${SCRIPT_DIR}/build.log 2>&1 diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 4f97af694d..fbbf6d66ad 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -854,11 +854,10 @@ static __always_inline unsigned long bpf_get_mm_counter(struct mm_struct *mm, { long val; - // See 6.2 kernel commit: https://github.com/torvalds/linux/commit/f1a7941243c102a44e8847e3b94ff4ff3ec56f25 -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 2, 0) - bpf_probe_read_kernel(&val, sizeof(val), &mm->rss_stat.count[member]); -#else +#ifdef HAS_RSS_STAT_ARRAY bpf_probe_read_kernel(&val, sizeof(val), &mm->rss_stat[member].count); +#else + bpf_probe_read_kernel(&val, sizeof(val), &mm->rss_stat.count[member]); #endif if (val < 0) val = 0; diff --git a/driver/configure/Makefile.inc.in b/driver/configure/Makefile.inc.in index 8e1e5d9fb4..54ec4a5a1f 100644 --- a/driver/configure/Makefile.inc.in +++ b/driver/configure/Makefile.inc.in @@ -4,10 +4,10 @@ MODULE_MAKEFILE_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) HAS_@CONFIGURE_MODULE@ := $(shell env -i PATH="$(PATH)" KERNELDIR="$(KERNELDIR)" sh $(MODULE_MAKEFILE_DIR)/build.sh ; echo $$?) ifeq ($(HAS_@CONFIGURE_MODULE@),0) -$(info [configure] Setting HAS_@CONFIGURE_MODULE@ flag) +$(info [configure-kmod] Setting HAS_@CONFIGURE_MODULE@ flag) ccflags-y += -DHAS_@CONFIGURE_MODULE@ else HAS_@CONFIGURE_MODULE@_OUT := $(shell cat $(MODULE_MAKEFILE_DIR)/build.log) -$(info [configure] Build output for HAS_@CONFIGURE_MODULE@:) -$(info [configure] $(HAS_@CONFIGURE_MODULE@_OUT)) +$(info [configure-kmod] Build output for HAS_@CONFIGURE_MODULE@:) +$(info [configure-kmod] $(HAS_@CONFIGURE_MODULE@_OUT)) endif From 8a893b7260e39056b2d87dcc8dceedd8ef821e26 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 7 Mar 2024 09:37:03 +0100 Subject: [PATCH 2/3] fix(driver/bpf): fix configure modules installation for bpf. Now we are able to build bpf probe from installed path. Signed-off-by: Federico Di Pierro --- driver/bpf/CMakeLists.txt | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/driver/bpf/CMakeLists.txt b/driver/bpf/CMakeLists.txt index 8fd0353cc4..c4ed549615 100644 --- a/driver/bpf/CMakeLists.txt +++ b/driver/bpf/CMakeLists.txt @@ -42,6 +42,10 @@ set(BPF_SOURCES types.h ) +if(NOT DEFINED DRIVER_BPF_COMPONENT_NAME) + set(DRIVER_BPF_COMPONENT_NAME ${DRIVER_COMPONENT_NAME}) +endif() + # Append driver headers too since they are used by bpf headers file(GLOB DRIVER_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../*.h) list(APPEND BPF_SOURCES ${DRIVER_HEADERS}) @@ -55,6 +59,12 @@ foreach(SOURCE IN LISTS BPF_SOURCES) list(APPEND INSTALL_SET ${CMAKE_CURRENT_BINARY_DIR}/src/${FILENAME}) endforeach() +install(FILES + ${INSTALL_SET} + DESTINATION "src/${DRIVER_PACKAGE_NAME}-${DRIVER_VERSION}/bpf" + COMPONENT ${DRIVER_BPF_COMPONENT_NAME} +) + # # Copy all the "configure" modules # @@ -66,20 +76,12 @@ foreach(subdir ${configure_modules}) configure_file(configure/Makefile src/configure/${CONFIGURE_MODULE}/Makefile COPYONLY) configure_file(configure/build.sh src/configure/${CONFIGURE_MODULE}/build.sh COPYONLY) configure_file(configure/Makefile.inc.in src/configure/${CONFIGURE_MODULE}/Makefile.inc) - list(APPEND INSTALL_SET + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/build.sh" "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/test.c" "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/Makefile" - "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/Makefile.inc") + "${CMAKE_CURRENT_BINARY_DIR}/src/configure/${CONFIGURE_MODULE}/Makefile.inc" + DESTINATION "src/${DRIVER_PACKAGE_NAME}-${DRIVER_VERSION}/bpf/configure/${CONFIGURE_MODULE}" + COMPONENT ${DRIVER_BPF_COMPONENT_NAME}) endif() -endforeach() - -if(NOT DEFINED DRIVER_BPF_COMPONENT_NAME) - set(DRIVER_BPF_COMPONENT_NAME ${DRIVER_COMPONENT_NAME}) -endif() - -install(FILES - ${INSTALL_SET} - DESTINATION "src/${DRIVER_PACKAGE_NAME}-${DRIVER_VERSION}/bpf" - COMPONENT ${DRIVER_BPF_COMPONENT_NAME} -) +endforeach() \ No newline at end of file From 3746251ca7ddf24561565ac430fbe17f97a3d8f7 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 11 Mar 2024 09:53:46 +0100 Subject: [PATCH 3/3] chore(driver/bpf): move `BPF_PROBE` macro definitions to types.h. Signed-off-by: Federico Di Pierro --- driver/bpf/configure/RSS_STAT_ARRAY/test.c | 15 --------------- driver/bpf/probe.c | 10 ---------- driver/bpf/types.h | 10 ++++++++++ 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/driver/bpf/configure/RSS_STAT_ARRAY/test.c b/driver/bpf/configure/RSS_STAT_ARRAY/test.c index 8ba3f65b43..d102f7a132 100644 --- a/driver/bpf/configure/RSS_STAT_ARRAY/test.c +++ b/driver/bpf/configure/RSS_STAT_ARRAY/test.c @@ -14,27 +14,12 @@ or GPL2.txt for full copies of the license. */ #include "../../quirks.h" - -#include - #include "../../ppm_events_public.h" -#include "../../bpf_helpers.h" #include "../../types.h" -#include "../../maps.h" // struct mm_struct declaration #include -#ifdef BPF_SUPPORTS_RAW_TRACEPOINTS -#define BPF_PROBE(prefix, event, type) \ -__bpf_section(TP_NAME #event) \ -int bpf_##event(struct type *ctx) -#else -#define BPF_PROBE(prefix, event, type) \ -__bpf_section(TP_NAME prefix #event) \ -int bpf_##event(struct type *ctx) -#endif - BPF_PROBE("signal/", signal_deliver, signal_deliver_args) { long val; diff --git a/driver/bpf/probe.c b/driver/bpf/probe.c index bb1feba3ac..bb9e570f3f 100644 --- a/driver/bpf/probe.c +++ b/driver/bpf/probe.c @@ -27,16 +27,6 @@ or GPL2.txt for full copies of the license. #include "fillers.h" #include "builtins.h" -#ifdef BPF_SUPPORTS_RAW_TRACEPOINTS -#define BPF_PROBE(prefix, event, type) \ -__bpf_section(TP_NAME #event) \ -int bpf_##event(struct type *ctx) -#else -#define BPF_PROBE(prefix, event, type) \ -__bpf_section(TP_NAME prefix #event) \ -int bpf_##event(struct type *ctx) -#endif - #define __NR_ia32_socketcall 102 BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args) diff --git a/driver/bpf/types.h b/driver/bpf/types.h index 87a0b6b538..9af3eedcc8 100644 --- a/driver/bpf/types.h +++ b/driver/bpf/types.h @@ -24,6 +24,16 @@ or GPL2.txt for full copies of the license. #define TP_NAME "tracepoint/" #endif +#ifdef BPF_SUPPORTS_RAW_TRACEPOINTS +#define BPF_PROBE(prefix, event, type) \ +__bpf_section(TP_NAME #event) \ +int bpf_##event(struct type *ctx) +#else +#define BPF_PROBE(prefix, event, type) \ +__bpf_section(TP_NAME prefix #event) \ +int bpf_##event(struct type *ctx) +#endif + #ifdef BPF_SUPPORTS_RAW_TRACEPOINTS struct sys_enter_args { unsigned long regs;