From 82e1c645f4650c482226de2408a3aaf68151273c Mon Sep 17 00:00:00 2001 From: Mattia Meleleo Date: Thu, 5 Oct 2023 15:07:36 +0200 Subject: [PATCH] compile pahole from source in Dockerfile --- Makefile | 2 +- non-GPL/Events/Lib/EbpfEvents.c | 34 ++++++++++---- testing/kernel_builder/Dockerfile.new | 19 ++++++++ .../{Dockerfile => Dockerfile.old} | 1 - testing/kernel_builder/Makefile | 6 ++- testing/kernel_builder/build.sh | 19 +++++--- testing/kernel_builder/config.custom | 10 ++-- testing/testrunner/tests.go | 47 ++++++++++++------- testing/testrunner/utils.go | 28 +++++------ 9 files changed, 111 insertions(+), 55 deletions(-) create mode 100644 testing/kernel_builder/Dockerfile.new rename testing/kernel_builder/{Dockerfile => Dockerfile.old} (73%) diff --git a/Makefile b/Makefile index 892f65c7..063d0659 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ CONTAINER_PULL_TAG ?= 20221121-1315 CONTAINER_LOCAL_TAG ?= ebpf-builder:${USER}-latest IMAGEPACK_REPOSITORY ?= ghcr.io/elastic/ebpf-imagepack -IMAGEPACK_PULL_TAG ?= 20231002-1224 +IMAGEPACK_PULL_TAG ?= 20231006-0053 ifdef BUILD_CONTAINER_IMAGE CONTAINER_IMAGE = ${CONTAINER_LOCAL_TAG} diff --git a/non-GPL/Events/Lib/EbpfEvents.c b/non-GPL/Events/Lib/EbpfEvents.c index afdd6bc4..b3a2dc21 100644 --- a/non-GPL/Events/Lib/EbpfEvents.c +++ b/non-GPL/Events/Lib/EbpfEvents.c @@ -123,7 +123,6 @@ const struct btf_type *resolve_btf_type_by_func(struct btf *btf, const char *fun continue; const struct btf_type *btf_type_ptr = btf__type_by_id(btf, btf_type); - if (!btf_is_func(btf_type_ptr)) continue; @@ -145,6 +144,7 @@ const struct btf_type *resolve_btf_type_by_func(struct btf *btf, const char *fun } out: + verbose("resolve_btf_type_by_func(%s): not found\n", func); return NULL; } @@ -156,8 +156,6 @@ static int resolve_btf_func_arg_idx(struct btf *btf, const char *func, const cha const struct btf_type *proto_btf_type_ptr = resolve_btf_type_by_func(btf, func); if (!proto_btf_type_ptr) goto out; - if (!arg) - goto out; struct btf_param *params = btf_params(proto_btf_type_ptr); for (int j = 0; j < btf_vlen(proto_btf_type_ptr); j++) { @@ -170,6 +168,7 @@ static int resolve_btf_func_arg_idx(struct btf *btf, const char *func, const cha goto out; } } + verbose("resolve_btf_func_arg_idx(%s, %s): not found\n", func, arg); out: return ret; @@ -198,6 +197,8 @@ static int resolve_btf_func_ret_idx(struct btf *btf, const char *func) int r = resolve_btf_func_arg_idx(btf, #func, #arg); \ if (r >= 0) \ __r = 0; \ + else \ + verbose("fill func arg idx (%s, %s): %d\n", #func, #arg, r); \ obj->rodata->arg__##func##__##arg##__ = r; \ __r; \ }) @@ -209,6 +210,8 @@ static int resolve_btf_func_ret_idx(struct btf *btf, const char *func) int r = resolve_btf_func_ret_idx(btf, #func); \ if (r >= 0) \ __r = 0; \ + else \ + verbose("fill func ret idx (%s): %d\n", #func, r); \ obj->rodata->ret__##func##__ = r; \ __r; \ }) @@ -223,6 +226,8 @@ static int resolve_btf_func_ret_idx(struct btf *btf, const char *func) if (r >= 0) { \ obj->rodata->exists__##func##__##arg##__ = true; \ __r = 0; \ + } else { \ + verbose("fill func arg exists (%s, %s): %d\n", #func, #arg, r); \ } \ __r; \ }) @@ -236,6 +241,8 @@ static int resolve_btf_func_ret_idx(struct btf *btf, const char *func) int r = resolve_btf_field_off(btf, #struct, #field); \ if (r >= 0) \ __r = 0; \ + else \ + verbose("fill field offset (%s, %s): %d\n", #struct, #field, r); \ obj->rodata->off__##struct##__##field##__ = r; \ __r; \ }) @@ -659,6 +666,7 @@ int ebpf_event_ctx__new(struct ebpf_event_ctx **ctx, ebpf_event_handler_fn cb, u /* EventProbe_bpf__open doesn't report errors, hard to find something * that fits perfect here */ + verbose("EventProbe_bpf__open: %d\n", err); err = -ENOENT; goto out_destroy_probe; } @@ -666,24 +674,34 @@ int ebpf_event_ctx__new(struct ebpf_event_ctx **ctx, ebpf_event_handler_fn cb, u probe->rodata->consumer_pid = getpid(); err = probe_fill_relos(btf, probe); - if (err != 0) + if (err != 0) { + verbose("probe_fill_relos: %d\n", err); goto out_destroy_probe; + } err = probe_resize_maps(probe); - if (err != 0) + if (err != 0) { + verbose("probe_resize_maps: %d\n", err); goto out_destroy_probe; + } err = probe_set_autoload(btf, probe, features); - if (err != 0) + if (err != 0) { + verbose("probe_set_autoload: %d\n", err); goto out_destroy_probe; + } err = EventProbe_bpf__load(probe); - if (err != 0) + if (err != 0) { + verbose("EventProbe_bpf__load: %d\n", err); goto out_destroy_probe; + } err = EventProbe_bpf__attach(probe); - if (err != 0) + if (err != 0) { + verbose("EventProbe_bpf__attach: %d\n", err); goto out_destroy_probe; + } if (!ctx) goto out_destroy_probe; diff --git a/testing/kernel_builder/Dockerfile.new b/testing/kernel_builder/Dockerfile.new new file mode 100644 index 00000000..989251f5 --- /dev/null +++ b/testing/kernel_builder/Dockerfile.new @@ -0,0 +1,19 @@ +from debian:bullseye + +RUN dpkg --add-architecture arm64 +RUN apt-get -y update +RUN apt-get -y install \ + git gcc make libssl-dev bison flex bc libelf-dev python3 \ + gcc-aarch64-linux-gnu curl xz-utils dwarves \ + cmake zlib1g libdw1 libdw-dev + +RUN git clone https://git.kernel.org/pub/scm/devel/pahole/pahole.git /pahole +WORKDIR /pahole +RUN git submodule update --init --recursive +RUN mkdir /pahole/build +WORKDIR /pahole/build +RUN cmake -DBUILD_SHARED_LIBS=OFF .. +RUN make install + +WORKDIR /work +CMD ./build.sh diff --git a/testing/kernel_builder/Dockerfile b/testing/kernel_builder/Dockerfile.old similarity index 73% rename from testing/kernel_builder/Dockerfile rename to testing/kernel_builder/Dockerfile.old index 4b11f806..9d25eba5 100644 --- a/testing/kernel_builder/Dockerfile +++ b/testing/kernel_builder/Dockerfile.old @@ -1,7 +1,6 @@ from debian:bullseye RUN dpkg --add-architecture arm64 -RUN echo "deb http://deb.debian.org/debian bullseye-backports main" >> /etc/apt/sources.list RUN apt-get -y update RUN apt-get -y install \ git gcc make libssl-dev bison flex bc libelf-dev python3 \ diff --git a/testing/kernel_builder/Makefile b/testing/kernel_builder/Makefile index 7d7df0af..a041a87c 100644 --- a/testing/kernel_builder/Makefile +++ b/testing/kernel_builder/Makefile @@ -4,7 +4,9 @@ IMAGE=kernel-builder-local TAG=latest all: - ${CONTAINER_ENGINE} run -v ${PWD}:/work ${IMAGE}:${TAG} + ${CONTAINER_ENGINE} run -v ${PWD}:/work ${IMAGE}-old:${TAG} + ${CONTAINER_ENGINE} run -v ${PWD}:/work ${IMAGE}-new:${TAG} image: - ${CONTAINER_ENGINE} build . -t ${IMAGE}:${TAG} + ${CONTAINER_ENGINE} build -f Dockerfile.old -t ${IMAGE}-old:${TAG} + ${CONTAINER_ENGINE} build -f Dockerfile.new -t ${IMAGE}-new:${TAG} diff --git a/testing/kernel_builder/build.sh b/testing/kernel_builder/build.sh index 62fc1289..14a8a3e9 100755 --- a/testing/kernel_builder/build.sh +++ b/testing/kernel_builder/build.sh @@ -18,16 +18,14 @@ readonly BUILD_ARCHES=( # We hit every minor release here, and grab a number of different patch # releases from each LTS series (e.g. 5.10, 5.15) -readonly BUILD_VERSIONS=( +readonly BUILD_VERSIONS_PAHOLE_120=( "5.10.16" # Oldest we support - "5.10.50" "5.10.130" "5.11" "5.12" "5.13" "5.14" "5.15" - "5.15.50" "5.15.133" "5.16" "5.17" @@ -36,6 +34,9 @@ readonly BUILD_VERSIONS=( "6.0" "6.1" "6.1.55" +) + +readonly BUILD_VERSIONS_PAHOLE_SOURCE=( "6.2" "6.3" "6.4" @@ -103,9 +104,15 @@ fetch_and_build() { } main() { - for version in ${BUILD_VERSIONS[@]}; do - fetch_and_build $version - done + if [ "$(pahole --version)" = "v1.20" ]; then + for version in ${BUILD_VERSIONS_PAHOLE_120[@]}; do + fetch_and_build $version + done + else + for version in ${BUILD_VERSIONS_PAHOLE_SOURCE[@]}; do + fetch_and_build $version + done + fi } main diff --git a/testing/kernel_builder/config.custom b/testing/kernel_builder/config.custom index 1576c188..36b297db 100644 --- a/testing/kernel_builder/config.custom +++ b/testing/kernel_builder/config.custom @@ -2,15 +2,12 @@ CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y CONFIG_BPF_JIT_ALWAYS_ON=y -CONFIG_DEBUG_INFO=y # Enable BTF -CONFIG_DEBUG_INFO_DWARF4=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_BTF=y CONFIG_DEBUG_INFO_REDUCED=n - -# Enable /sys/kernel/debug/tracing/events/syscalls -CONFIG_FTRACE_SYSCALLS=y +CONFIG_DEBUG_INFO_DWARF4=y # Enable securityfs CONFIG_SECURITYFS=y @@ -46,6 +43,9 @@ CONFIG_CGROUP_NET_CLASSID=y CONFIG_FTRACE=y CONFIG_FUNCTION_TRACER=y CONFIG_KPROBES=y +CONFIG_KPROBES_ON_FTRACE=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_FPROBE=y # Enable IPv6 (not on by default in aarch64 defconfig) CONFIG_IPV6=y diff --git a/testing/testrunner/tests.go b/testing/testrunner/tests.go index 116a1428..8d28de12 100644 --- a/testing/testrunner/tests.go +++ b/testing/testrunner/tests.go @@ -18,28 +18,33 @@ import ( ) func TestFeaturesCorrect(et *EventsTraceInstance) { - var buf syscall.Utsname - if err := syscall.Uname(&buf); err != nil { + var utsname syscall.Utsname + if err := syscall.Uname(&utsname); err != nil { TestFail(fmt.Sprintf("Failed to run uname: %s", err)) } - archBytes := []byte{} - for _, b := range buf.Machine { - if b == 0 { - break + int8ArrayToString := func(arr [65]int8) string { + var buf []byte + for _, el := range arr { + if el == 0 { + break + } + buf = append(buf, byte(el)) } - - archBytes = append(archBytes, byte(b)) + return string(buf) + } + contains := func(s []string, str string) bool { + for _, el := range s { + if el == str { + return true + } + } + return false } - arch := string(archBytes) - // BPF trampolines are only supported on x86 at present. - // - // As of June 2022, there is a patchset circulating that will add support - // to ARM64 (https://lwn.net/Articles/899093/). This check should be - // updated when that is merged into the mainline such that it ensures BPF - // trampolines are disabled on all aarch64 kernels pre-. + arch := int8ArrayToString(utsname.Machine) + kernelVersion := int8ArrayToString(utsname.Release) + switch arch { case "x86_64": // All x86 kernels in the CI test matrix currently enable bpf @@ -49,9 +54,15 @@ func TestFeaturesCorrect(et *EventsTraceInstance) { // handle it here. AssertTrue(et.InitMsg.Features.BpfTramp) case "aarch64": - AssertFalse(et.InitMsg.Features.BpfTramp) + hasBpfTramp := []string{"6.4.0", "6.4.16", "6.5.0"} + + if contains(hasBpfTramp, kernelVersion) { + AssertTrue(et.InitMsg.Features.BpfTramp) + } else { + AssertFalse(et.InitMsg.Features.BpfTramp) + } default: - TestFail(fmt.Sprintf("Unknown arch %s, please add to the TestFeaturesCorrect test", arch)) + TestFail(fmt.Sprintf("unknown arch %s, please add to the TestFeaturesCorrect test", arch)) } } diff --git a/testing/testrunner/utils.go b/testing/testrunner/utils.go index 039a2476..a70a8a55 100644 --- a/testing/testrunner/utils.go +++ b/testing/testrunner/utils.go @@ -26,11 +26,11 @@ import ( // This is a JSON type printed by the test binaries (not by EventsTrace), it's // used all over the place, so define it here to save space type TestPidInfo struct { - Tid int64 `json:"tid"` - Tgid int64 `json:"tgid"` - Ppid int64 `json:"ppid"` - Pgid int64 `json:"pgid"` - Sid int64 `json:"sid"` + Tid int64 `json:"tid"` + Tgid int64 `json:"tgid"` + Ppid int64 `json:"ppid"` + Pgid int64 `json:"pgid"` + Sid int64 `json:"sid"` CapPermitted uint64 `json:"cap_permitted,string"` CapEffective uint64 `json:"cap_effective,string"` } @@ -53,12 +53,12 @@ type PidInfo struct { } type CredInfo struct { - Ruid int64 `json:"ruid"` - Rgid int64 `json:"rgid"` - Euid int64 `json:"euid"` - Egid int64 `json:"egid"` - Suid int64 `json:"suid"` - Sgid int64 `json:"sgid"` + Ruid int64 `json:"ruid"` + Rgid int64 `json:"rgid"` + Euid int64 `json:"euid"` + Egid int64 `json:"egid"` + Suid int64 `json:"suid"` + Sgid int64 `json:"sgid"` CapPermitted uint64 `json:"cap_permitted,string"` CapEffective uint64 `json:"cap_effective,string"` } @@ -79,9 +79,9 @@ type NetInfo struct { } type ProcessForkEvent struct { - ParentPids PidInfo `json:"parent_pids"` - ChildPids PidInfo `json:"child_pids"` - Creds CredInfo `json:"creds"` + ParentPids PidInfo `json:"parent_pids"` + ChildPids PidInfo `json:"child_pids"` + Creds CredInfo `json:"creds"` } type ProcessExecEvent struct {