From 24581f6b5ad4d9b71f183a4f2e07f27ab7deeee3 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 23 Jan 2025 09:07:18 +0100 Subject: [PATCH 1/9] new(driver/modern_bpf,userspace/libpman): support multiple programs for each event. Try to inject each of them until success. This allows us to inject `bpf_loop` sendmmsg and recvmmsg programs where supported, and fallback at just sending first message where it isn't. Signed-off-by: Federico Di Pierro --- driver/modern_bpf/helpers/base/shared_size.h | 3 - .../syscall_dispatched_events/recvmmsg.bpf.c | 63 +++- .../syscall_dispatched_events/sendmmsg.bpf.c | 60 ++- userspace/libpman/CMakeLists.txt | 1 + userspace/libpman/include/libpman.h | 8 + userspace/libpman/src/events_prog_names.c | 342 +++++++++++++++++ userspace/libpman/src/events_prog_names.h | 347 +----------------- userspace/libpman/src/lifecycle.c | 38 ++ userspace/libpman/src/maps.c | 25 +- .../engine/modern_bpf/scap_modern_bpf.c | 1 + 10 files changed, 525 insertions(+), 363 deletions(-) create mode 100644 userspace/libpman/src/events_prog_names.c diff --git a/driver/modern_bpf/helpers/base/shared_size.h b/driver/modern_bpf/helpers/base/shared_size.h index 7d81007ba7..61e24dc7ae 100644 --- a/driver/modern_bpf/helpers/base/shared_size.h +++ b/driver/modern_bpf/helpers/base/shared_size.h @@ -26,9 +26,6 @@ /* Maximum number of `iovec` structures that we can analyze. */ #define MAX_IOVCNT 32 -/* Maximum number of supported sendmmsg/recvmmsg messages */ -#define MAX_SENDMMSG_RECVMMSG_SIZE 8 - /* Maximum number of `pollfd` structures that we can analyze. */ #define MAX_POLLFD 16 diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c index e6aaf15f92..f0a2021fb5 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c @@ -159,17 +159,60 @@ int BPF_PROG(recvmmsg_x, struct pt_regs *regs, long ret) { .ctx = ctx, }; - // We can't use bpf_loop() helper since the below check triggers a verifier failure: - // see - // https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u - /*if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) { - uint32_t nr_loops = ret < 1024 ? ret : 1024; - bpf_loop(nr_loops, handle_exit, &data, 0); - } else {*/ - for(int i = 0; i < ret && i < MAX_SENDMMSG_RECVMMSG_SIZE; i++) { - handle_exit(i, &data); + uint32_t nr_loops = ret < 1024 ? ret : 1024; + bpf_loop(nr_loops, handle_exit, &data, 0); + + return 0; +} + +SEC("tp_btf/sys_exit") +int BPF_PROG(recvmmsg_old_x, struct pt_regs *regs, long ret) { + if(ret <= 0) { + unsigned long fd = 0; + struct auxiliary_map *auxmap = auxmap__get(); + if(!auxmap) { + return 0; + } + + auxmap__preload_event_header(auxmap, PPME_SOCKET_RECVMMSG_X); + + /* Parameter 1: res (type: PT_ERRNO) */ + auxmap__store_s64_param(auxmap, ret); + + /* Parameter 2: fd (type: PT_FD) */ + extract__network_args(&fd, 1, regs); + auxmap__store_s64_param(auxmap, (int64_t)(int32_t)fd); + + /* Parameter 3: size (type: PT_UINT32) */ + auxmap__store_u32_param(auxmap, 0); + + /* Parameter 4: data (type: PT_BYTEBUF) */ + auxmap__store_empty_param(auxmap); + + /* Parameter 5: tuple (type: PT_SOCKTUPLE) */ + auxmap__store_empty_param(auxmap); + + /* Parameter 6: msg_control (type: PT_BYTEBUF) */ + auxmap__store_empty_param(auxmap); + + auxmap__finalize_event_header(auxmap); + + auxmap__submit_event(auxmap); + return 0; } - //} + + /* Collect parameters at the beginning to manage socketcalls */ + unsigned long args[2]; + extract__network_args(args, 2, regs); + recvmmsg_data_t data = { + .fd = args[0], + .mmh = (struct mmsghdr *)args[1], + .regs = regs, + .ctx = ctx, + }; + + // Send only first message + handle_exit(0, &data); return 0; } diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c index 1470664b12..e69750cd76 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c @@ -152,17 +152,57 @@ int BPF_PROG(sendmmsg_x, struct pt_regs *regs, long ret) { .ctx = ctx, }; - // We can't use bpf_loop() helper since the below check triggers a verifier failure: - // see - // https://lore.kernel.org/bpf/CAGQdkDt9zyQwr5JyftXqL=OLKscNcqUtEteY4hvOkx2S4GdEkQ@mail.gmail.com/T/#u - /*if(bpf_core_enum_value_exists(enum bpf_func_id, BPF_FUNC_loop)) { - uint32_t nr_loops = ret < 1024 ? ret : 1024; - bpf_loop(nr_loops, handle_exit, &data, 0); - } else {*/ - for(int i = 0; i < ret && i < MAX_SENDMMSG_RECVMMSG_SIZE; i++) { - handle_exit(i, &data); + uint32_t nr_loops = ret < 1024 ? ret : 1024; + bpf_loop(nr_loops, handle_exit, &data, 0); + + return 0; +} + +SEC("tp_btf/sys_exit") +int BPF_PROG(sendmmsg_old_x, struct pt_regs *regs, long ret) { + if(ret <= 0) { + unsigned long fd = 0; + struct auxiliary_map *auxmap = auxmap__get(); + if(!auxmap) { + return 0; + } + + auxmap__preload_event_header(auxmap, PPME_SOCKET_SENDMMSG_X); + + /* Parameter 1: res (type: PT_ERRNO) */ + auxmap__store_s64_param(auxmap, ret); + + /* Parameter 2: fd (type: PT_FD) */ + extract__network_args(&fd, 1, regs); + auxmap__store_s64_param(auxmap, (int64_t)(int32_t)fd); + + /* Parameter 3: size (type: PT_UINT32) */ + auxmap__store_u32_param(auxmap, 0); + + /* Parameter 4: data (type: PT_BYTEBUF) */ + auxmap__store_empty_param(auxmap); + + /* Parameter 5: tuple (type: PT_SOCKTUPLE) */ + auxmap__store_empty_param(auxmap); + + auxmap__finalize_event_header(auxmap); + + auxmap__submit_event(auxmap); + return 0; } - //} + + /* Collect parameters at the beginning to manage socketcalls */ + unsigned long args[2]; + extract__network_args(args, 2, regs); + sendmmsg_exit_t data = { + .fd = args[0], + .mmh = (struct mmsghdr *)args[1], + .regs = regs, + .ctx = ctx, + }; + + // Only first message + handle_exit(0, &data); return 0; } diff --git a/userspace/libpman/CMakeLists.txt b/userspace/libpman/CMakeLists.txt index b5d982b0df..0b8dd4b9b0 100644 --- a/userspace/libpman/CMakeLists.txt +++ b/userspace/libpman/CMakeLists.txt @@ -27,6 +27,7 @@ add_library( src/configuration.c src/state.c src/sc_set.c + src/events_prog_names.c ) target_include_directories( diff --git a/userspace/libpman/include/libpman.h b/userspace/libpman/include/libpman.h index aa8cc827e8..fe34462a68 100644 --- a/userspace/libpman/include/libpman.h +++ b/userspace/libpman/include/libpman.h @@ -94,6 +94,14 @@ bool pman_check_support(); */ int pman_open_probe(void); +/** + * @brief Prepares the bpf skeleton object checking if + * it satisfies each events_prog_name feature requirements for each prog. + * + * @return `0` on success, `errno` in case of error. + */ +int pman_prepare_progs_before_loading(void); + /** * @brief Load into the kernel all the programs and maps * contained into the skeleton. diff --git a/userspace/libpman/src/events_prog_names.c b/userspace/libpman/src/events_prog_names.c new file mode 100644 index 0000000000..4ec640fb4b --- /dev/null +++ b/userspace/libpman/src/events_prog_names.c @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: Apache-2.0 +/* +Copyright (C) 2025 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#include "events_prog_names.h" +/* + * For every event here we have the name of the corresponding bpf program. + * We can have multiple names in case we need to check the right program + * that needs to be loaded, eg: because of different bpf features. + */ +event_prog_t event_prog_names[PPM_EVENT_MAX][MAX_FEATURE_CHECKS] = { + [PPME_GENERIC_E] = {{"generic_e", 0}}, + [PPME_GENERIC_X] = {{"generic_x", 0}}, + [PPME_SYSCALL_GETCWD_E] = {{"getcwd_e", 0}}, + [PPME_SYSCALL_GETCWD_X] = {{"getcwd_x", 0}}, + [PPME_SYSCALL_GETDENTS_E] = {{"getdents_e", 0}}, + [PPME_SYSCALL_GETDENTS_X] = {{"getdents_x", 0}}, + [PPME_SYSCALL_GETDENTS64_E] = {{"getdents64_e", 0}}, + [PPME_SYSCALL_GETDENTS64_X] = {{"getdents64_x", 0}}, + [PPME_SYSCALL_EPOLLWAIT_E] = {{"epoll_wait_e", 0}}, + [PPME_SYSCALL_EPOLLWAIT_X] = {{"epoll_wait_x", 0}}, + [PPME_SOCKET_GETPEERNAME_E] = {{"getpeername_e", 0}}, + [PPME_SOCKET_GETPEERNAME_X] = {{"getpeername_x", 0}}, + [PPME_SOCKET_GETSOCKNAME_E] = {{"getsockname_e", 0}}, + [PPME_SOCKET_GETSOCKNAME_X] = {{"getsockname_x", 0}}, + [PPME_SYSCALL_MKDIR_2_E] = {{"mkdir_e", 0}}, + [PPME_SYSCALL_MKDIR_2_X] = {{"mkdir_x", 0}}, + [PPME_SYSCALL_MMAP_E] = {{"mmap_e", 0}}, + [PPME_SYSCALL_MMAP_X] = {{"mmap_x", 0}}, + [PPME_SYSCALL_MUNMAP_E] = {{"munmap_e", 0}}, + [PPME_SYSCALL_MUNMAP_X] = {{"munmap_x", 0}}, + [PPME_SYSCALL_OPEN_E] = {{"open_e", 0}}, + [PPME_SYSCALL_OPEN_X] = {{"open_x", 0}}, + [PPME_SYSCALL_OPENAT_2_E] = {{"openat_e", 0}}, + [PPME_SYSCALL_OPENAT_2_X] = {{"openat_x", 0}}, + [PPME_SYSCALL_OPENAT2_E] = {{"openat2_e", 0}}, + [PPME_SYSCALL_OPENAT2_X] = {{"openat2_x", 0}}, + [PPME_SYSCALL_OPEN_BY_HANDLE_AT_E] = {{"open_by_handle_at_e", 0}}, + [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = {{"open_by_handle_at_x", 0}}, + [PPME_SYSCALL_CLOSE_E] = {{"close_e", 0}}, + [PPME_SYSCALL_CLOSE_X] = {{"close_x", 0}}, + [PPME_SYSCALL_COPY_FILE_RANGE_E] = {{"copy_file_range_e", 0}}, + [PPME_SYSCALL_COPY_FILE_RANGE_X] = {{"copy_file_range_x", 0}}, + [PPME_SYSCALL_CREAT_E] = {{"creat_e", 0}}, + [PPME_SYSCALL_CREAT_X] = {{"creat_x", 0}}, + [PPME_SYSCALL_DUP_1_E] = {{"dup_e", 0}}, + [PPME_SYSCALL_DUP_1_X] = {{"dup_x", 0}}, + [PPME_SYSCALL_DUP2_E] = {{"dup2_e", 0}}, + [PPME_SYSCALL_DUP2_X] = {{"dup2_x", 0}}, + [PPME_SYSCALL_DUP3_E] = {{"dup3_e", 0}}, + [PPME_SYSCALL_DUP3_X] = {{"dup3_x", 0}}, + [PPME_SYSCALL_CHDIR_E] = {{"chdir_e", 0}}, + [PPME_SYSCALL_CHDIR_X] = {{"chdir_x", 0}}, + [PPME_SYSCALL_CHMOD_E] = {{"chmod_e", 0}}, + [PPME_SYSCALL_CHMOD_X] = {{"chmod_x", 0}}, + [PPME_SYSCALL_CHROOT_E] = {{"chroot_e", 0}}, + [PPME_SYSCALL_CHROOT_X] = {{"chroot_x", 0}}, + [PPME_SYSCALL_FCHDIR_E] = {{"fchdir_e", 0}}, + [PPME_SYSCALL_FCHDIR_X] = {{"fchdir_x", 0}}, + [PPME_SYSCALL_FCHMOD_E] = {{"fchmod_e", 0}}, + [PPME_SYSCALL_FCHMOD_X] = {{"fchmod_x", 0}}, + [PPME_SYSCALL_FCHMODAT_E] = {{"fchmodat_e", 0}}, + [PPME_SYSCALL_FCHMODAT_X] = {{"fchmodat_x", 0}}, + [PPME_SYSCALL_MKDIRAT_E] = {{"mkdirat_e", 0}}, + [PPME_SYSCALL_MKDIRAT_X] = {{"mkdirat_x", 0}}, + [PPME_SYSCALL_RMDIR_2_E] = {{"rmdir_e", 0}}, + [PPME_SYSCALL_RMDIR_2_X] = {{"rmdir_x", 0}}, + [PPME_SYSCALL_EVENTFD_E] = {{"eventfd_e", 0}}, + [PPME_SYSCALL_EVENTFD_X] = {{"eventfd_x", 0}}, + [PPME_SYSCALL_INOTIFY_INIT_E] = {{"inotify_init_e", 0}}, + [PPME_SYSCALL_INOTIFY_INIT_X] = {{"inotify_init_x", 0}}, + [PPME_SYSCALL_TIMERFD_CREATE_E] = {{"timerfd_create_e", 0}}, + [PPME_SYSCALL_TIMERFD_CREATE_X] = {{"timerfd_create_x", 0}}, + [PPME_SYSCALL_USERFAULTFD_E] = {{"userfaultfd_e", 0}}, + [PPME_SYSCALL_USERFAULTFD_X] = {{"userfaultfd_x", 0}}, + [PPME_SYSCALL_SIGNALFD_E] = {{"signalfd_e", 0}}, + [PPME_SYSCALL_SIGNALFD_X] = {{"signalfd_x", 0}}, + [PPME_SYSCALL_KILL_E] = {{"kill_e", 0}}, + [PPME_SYSCALL_KILL_X] = {{"kill_x", 0}}, + [PPME_SYSCALL_TGKILL_E] = {{"tgkill_e", 0}}, + [PPME_SYSCALL_TGKILL_X] = {{"tgkill_x", 0}}, + [PPME_SYSCALL_TKILL_E] = {{"tkill_e", 0}}, + [PPME_SYSCALL_TKILL_X] = {{"tkill_x", 0}}, + [PPME_SYSCALL_SECCOMP_E] = {{"seccomp_e", 0}}, + [PPME_SYSCALL_SECCOMP_X] = {{"seccomp_x", 0}}, + [PPME_SYSCALL_PTRACE_E] = {{"ptrace_e", 0}}, + [PPME_SYSCALL_PTRACE_X] = {{"ptrace_x", 0}}, + [PPME_SYSCALL_CAPSET_E] = {{"capset_e", 0}}, + [PPME_SYSCALL_CAPSET_X] = {{"capset_x", 0}}, + [PPME_SOCKET_SOCKET_E] = {{"socket_e", 0}}, + [PPME_SOCKET_SOCKET_X] = {{"socket_x", 0}}, + [PPME_SOCKET_CONNECT_E] = {{"connect_e", 0}}, + [PPME_SOCKET_CONNECT_X] = {{"connect_x", 0}}, + [PPME_SOCKET_SOCKETPAIR_E] = {{"socketpair_e", 0}}, + [PPME_SOCKET_SOCKETPAIR_X] = {{"socketpair_x", 0}}, + [PPME_SOCKET_ACCEPT_5_E] = {{"accept_e", 0}}, + [PPME_SOCKET_ACCEPT_5_X] = {{"accept_x", 0}}, + [PPME_SOCKET_BIND_E] = {{"bind_e", 0}}, + [PPME_SOCKET_BIND_X] = {{"bind_x", 0}}, + [PPME_SOCKET_LISTEN_E] = {{"listen_e", 0}}, + [PPME_SOCKET_LISTEN_X] = {{"listen_x", 0}}, + [PPME_SYSCALL_EXECVE_19_E] = {{"execve_e", 0}}, + [PPME_SYSCALL_EXECVE_19_X] = {{"execve_x", 0}}, + [PPME_SYSCALL_EXECVEAT_E] = {{"execveat_e", 0}}, + [PPME_SYSCALL_EXECVEAT_X] = {{"execveat_x", 0}}, + [PPME_SYSCALL_CLONE_20_E] = {{"clone_e", 0}}, + [PPME_SYSCALL_CLONE_20_X] = {{"clone_x", 0}}, + [PPME_SYSCALL_CLONE3_E] = {{"clone3_e", 0}}, + [PPME_SYSCALL_CLONE3_X] = {{"clone3_x", 0}}, + [PPME_SYSCALL_FORK_20_E] = {{"fork_e", 0}}, + [PPME_SYSCALL_FORK_20_X] = {{"fork_x", 0}}, + [PPME_SYSCALL_VFORK_20_E] = {{"vfork_e", 0}}, + [PPME_SYSCALL_VFORK_20_X] = {{"vfork_x", 0}}, + [PPME_SYSCALL_RENAME_E] = {{"rename_e", 0}}, + [PPME_SYSCALL_RENAME_X] = {{"rename_x", 0}}, + [PPME_SYSCALL_RENAMEAT_E] = {{"renameat_e", 0}}, + [PPME_SYSCALL_RENAMEAT_X] = {{"renameat_x", 0}}, + [PPME_SYSCALL_RENAMEAT2_E] = {{"renameat2_e", 0}}, + [PPME_SYSCALL_RENAMEAT2_X] = {{"renameat2_x", 0}}, + [PPME_SYSCALL_PIPE_E] = {{"pipe_e", 0}}, + [PPME_SYSCALL_PIPE_X] = {{"pipe_x", 0}}, + [PPME_SYSCALL_READV_E] = {{"readv_e", 0}}, + [PPME_SYSCALL_READV_X] = {{"readv_x", 0}}, + [PPME_SYSCALL_PREADV_E] = {{"preadv_e", 0}}, + [PPME_SYSCALL_PREADV_X] = {{"preadv_x", 0}}, + [PPME_SYSCALL_PREAD_E] = {{"pread64_e", 0}}, + [PPME_SYSCALL_PREAD_X] = {{"pread64_x", 0}}, + [PPME_SYSCALL_BPF_2_E] = {{"bpf_e", 0}}, + [PPME_SYSCALL_BPF_2_X] = {{"bpf_x", 0}}, + [PPME_SYSCALL_FLOCK_E] = {{"flock_e", 0}}, + [PPME_SYSCALL_FLOCK_X] = {{"flock_x", 0}}, + [PPME_SYSCALL_IOCTL_3_E] = {{"ioctl_e", 0}}, + [PPME_SYSCALL_IOCTL_3_X] = {{"ioctl_x", 0}}, + [PPME_SYSCALL_QUOTACTL_E] = {{"quotactl_e", 0}}, + [PPME_SYSCALL_QUOTACTL_X] = {{"quotactl_x", 0}}, + [PPME_SYSCALL_UNSHARE_E] = {{"unshare_e", 0}}, + [PPME_SYSCALL_UNSHARE_X] = {{"unshare_x", 0}}, + [PPME_SYSCALL_MOUNT_E] = {{"mount_e", 0}}, + [PPME_SYSCALL_MOUNT_X] = {{"mount_x", 0}}, + [PPME_SYSCALL_UMOUNT2_E] = {{"umount2_e", 0}}, + [PPME_SYSCALL_UMOUNT2_X] = {{"umount2_x", 0}}, + [PPME_SYSCALL_LINK_2_E] = {{"link_e", 0}}, + [PPME_SYSCALL_LINK_2_X] = {{"link_x", 0}}, + [PPME_SYSCALL_LINKAT_2_E] = {{"linkat_e", 0}}, + [PPME_SYSCALL_LINKAT_2_X] = {{"linkat_x", 0}}, + [PPME_SYSCALL_SYMLINK_E] = {{"symlink_e", 0}}, + [PPME_SYSCALL_SYMLINK_X] = {{"symlink_x", 0}}, + [PPME_SYSCALL_SYMLINKAT_E] = {{"symlinkat_e", 0}}, + [PPME_SYSCALL_SYMLINKAT_X] = {{"symlinkat_x", 0}}, + [PPME_SYSCALL_UNLINK_2_E] = {{"unlink_e", 0}}, + [PPME_SYSCALL_UNLINK_2_X] = {{"unlink_x", 0}}, + [PPME_SYSCALL_UNLINKAT_2_E] = {{"unlinkat_e", 0}}, + [PPME_SYSCALL_UNLINKAT_2_X] = {{"unlinkat_x", 0}}, + [PPME_SYSCALL_SETGID_E] = {{"setgid_e", 0}}, + [PPME_SYSCALL_SETGID_X] = {{"setgid_x", 0}}, + [PPME_SYSCALL_SETUID_E] = {{"setuid_e", 0}}, + [PPME_SYSCALL_SETUID_X] = {{"setuid_x", 0}}, + [PPME_SYSCALL_SETNS_E] = {{"setns_e", 0}}, + [PPME_SYSCALL_SETNS_X] = {{"setns_x", 0}}, + [PPME_SYSCALL_SETPGID_E] = {{"setpgid_e", 0}}, + [PPME_SYSCALL_SETPGID_X] = {{"setpgid_x", 0}}, + [PPME_SYSCALL_SETRESGID_E] = {{"setresgid_e", 0}}, + [PPME_SYSCALL_SETRESGID_X] = {{"setresgid_x", 0}}, + [PPME_SYSCALL_SETRESUID_E] = {{"setresuid_e", 0}}, + [PPME_SYSCALL_SETRESUID_X] = {{"setresuid_x", 0}}, + [PPME_SYSCALL_SETSID_E] = {{"setsid_e", 0}}, + [PPME_SYSCALL_SETSID_X] = {{"setsid_x", 0}}, + [PPME_SYSCALL_SETRLIMIT_E] = {{"setrlimit_e", 0}}, + [PPME_SYSCALL_SETRLIMIT_X] = {{"setrlimit_x", 0}}, + [PPME_SYSCALL_PRLIMIT_E] = {{"prlimit64_e", 0}}, + [PPME_SYSCALL_PRLIMIT_X] = {{"prlimit64_x", 0}}, + [PPME_SOCKET_SETSOCKOPT_E] = {{"setsockopt_e", 0}}, + [PPME_SOCKET_SETSOCKOPT_X] = {{"setsockopt_x", 0}}, + [PPME_SOCKET_SENDMSG_E] = {{"sendmsg_e", 0}}, + [PPME_SOCKET_SENDMSG_X] = {{"sendmsg_x", 0}}, + [PPME_SOCKET_SENDTO_E] = {{"sendto_e", 0}}, + [PPME_SOCKET_SENDTO_X] = {{"sendto_x", 0}}, + [PPME_SOCKET_RECVMSG_E] = {{"recvmsg_e", 0}}, + [PPME_SOCKET_RECVMSG_X] = {{"recvmsg_x", 0}}, + [PPME_SOCKET_RECVFROM_E] = {{"recvfrom_e", 0}}, + [PPME_SOCKET_RECVFROM_X] = {{"recvfrom_x", 0}}, + [PPME_SYSCALL_FCNTL_E] = {{"fcntl_e", 0}}, + [PPME_SYSCALL_FCNTL_X] = {{"fcntl_x", 0}}, + [PPME_SOCKET_SHUTDOWN_E] = {{"shutdown_e", 0}}, + [PPME_SOCKET_SHUTDOWN_X] = {{"shutdown_x", 0}}, + [PPME_SYSCALL_FSCONFIG_E] = {{"fsconfig_e", 0}}, + [PPME_SYSCALL_FSCONFIG_X] = {{"fsconfig_x", 0}}, + [PPME_SYSCALL_EPOLL_CREATE_E] = {{"epoll_create_e", 0}}, + [PPME_SYSCALL_EPOLL_CREATE_X] = {{"epoll_create_x", 0}}, + [PPME_SYSCALL_EPOLL_CREATE1_E] = {{"epoll_create1_e", 0}}, + [PPME_SYSCALL_EPOLL_CREATE1_X] = {{"epoll_create1_x", 0}}, + [PPME_SYSCALL_ACCESS_E] = {{"access_e", 0}}, + [PPME_SYSCALL_ACCESS_X] = {{"access_x", 0}}, + [PPME_SOCKET_GETSOCKOPT_E] = {{"getsockopt_e", 0}}, + [PPME_SOCKET_GETSOCKOPT_X] = {{"getsockopt_x", 0}}, + [PPME_SYSCALL_MPROTECT_E] = {{"mprotect_e", 0}}, + [PPME_SYSCALL_MPROTECT_X] = {{"mprotect_x", 0}}, + [PPME_SYSCALL_GETUID_E] = {{"getuid_e", 0}}, + [PPME_SYSCALL_GETUID_X] = {{"getuid_x", 0}}, + [PPME_SYSCALL_GETGID_E] = {{"getgid_e", 0}}, + [PPME_SYSCALL_GETGID_X] = {{"getgid_x", 0}}, + [PPME_SYSCALL_GETEUID_E] = {{"geteuid_e", 0}}, + [PPME_SYSCALL_GETEUID_X] = {{"geteuid_x", 0}}, + [PPME_SYSCALL_GETEGID_E] = {{"getegid_e", 0}}, + [PPME_SYSCALL_GETEGID_X] = {{"getegid_x", 0}}, + [PPME_SYSCALL_MLOCK_E] = {{"mlock_e", 0}}, + [PPME_SYSCALL_MLOCK_X] = {{"mlock_x", 0}}, + [PPME_SYSCALL_MLOCK2_E] = {{"mlock2_e", 0}}, + [PPME_SYSCALL_MLOCK2_X] = {{"mlock2_x", 0}}, + [PPME_SYSCALL_MUNLOCK_E] = {{"munlock_e", 0}}, + [PPME_SYSCALL_MUNLOCK_X] = {{"munlock_x", 0}}, + [PPME_SYSCALL_MLOCKALL_E] = {{"mlockall_e", 0}}, + [PPME_SYSCALL_MLOCKALL_X] = {{"mlockall_x", 0}}, + [PPME_SYSCALL_MUNLOCKALL_E] = {{"munlockall_e", 0}}, + [PPME_SYSCALL_MUNLOCKALL_X] = {{"munlockall_x", 0}}, + [PPME_SYSCALL_READ_E] = {{"read_e", 0}}, + [PPME_SYSCALL_READ_X] = {{"read_x", 0}}, + [PPME_SYSCALL_IO_URING_ENTER_E] = {{"io_uring_enter_e", 0}}, + [PPME_SYSCALL_IO_URING_ENTER_X] = {{"io_uring_enter_x", 0}}, + [PPME_SYSCALL_IO_URING_REGISTER_E] = {{"io_uring_register_e", 0}}, + [PPME_SYSCALL_IO_URING_REGISTER_X] = {{"io_uring_register_x", 0}}, + [PPME_SYSCALL_IO_URING_SETUP_E] = {{"io_uring_setup_e", 0}}, + [PPME_SYSCALL_IO_URING_SETUP_X] = {{"io_uring_setup_x", 0}}, + [PPME_SYSCALL_POLL_E] = {{"poll_e", 0}}, + [PPME_SYSCALL_POLL_X] = {{"poll_x", 0}}, + [PPME_SYSCALL_PPOLL_E] = {{"ppoll_e", 0}}, + [PPME_SYSCALL_PPOLL_X] = {{"ppoll_x", 0}}, + [PPME_SYSCALL_MMAP2_E] = {{"mmap2_e", 0}}, + [PPME_SYSCALL_MMAP2_X] = {{"mmap2_x", 0}}, + [PPME_SYSCALL_SEMGET_E] = {{"semget_e", 0}}, + [PPME_SYSCALL_SEMGET_X] = {{"semget_x", 0}}, + [PPME_SYSCALL_SEMCTL_E] = {{"semctl_e", 0}}, + [PPME_SYSCALL_SEMCTL_X] = {{"semctl_x", 0}}, + [PPME_SYSCALL_SELECT_E] = {{"select_e", 0}}, + [PPME_SYSCALL_SELECT_X] = {{"select_x", 0}}, + [PPME_SYSCALL_SPLICE_E] = {{"splice_e", 0}}, + [PPME_SYSCALL_SPLICE_X] = {{"splice_x", 0}}, + [PPME_SOCKET_RECVMMSG_E] = {{"recvmmsg_e", 0}}, + [PPME_SOCKET_RECVMMSG_X] = {{"recvmmsg_x", BPF_FUNC_loop}, {"recvmmsg_old_x", 0}}, + [PPME_SOCKET_SENDMMSG_E] = {{"sendmmsg_e", 0}}, + [PPME_SOCKET_SENDMMSG_X] = {{"sendmmsg_x", BPF_FUNC_loop}, {"sendmmsg_old_x", 0}}, + [PPME_SYSCALL_SEMOP_E] = {{"semop_e", 0}}, + [PPME_SYSCALL_SEMOP_X] = {{"semop_x", 0}}, + [PPME_SYSCALL_GETRESUID_E] = {{"getresuid_e", 0}}, + [PPME_SYSCALL_GETRESUID_X] = {{"getresuid_x", 0}}, + [PPME_SYSCALL_SENDFILE_E] = {{"sendfile_e", 0}}, + [PPME_SYSCALL_SENDFILE_X] = {{"sendfile_x", 0}}, + [PPME_SYSCALL_FUTEX_E] = {{"futex_e", 0}}, + [PPME_SYSCALL_FUTEX_X] = {{"futex_x", 0}}, + [PPME_SYSCALL_STAT_E] = {{"stat_e", 0}}, + [PPME_SYSCALL_STAT_X] = {{"stat_x", 0}}, + [PPME_SYSCALL_LSTAT_E] = {{"lstat_e", 0}}, + [PPME_SYSCALL_LSTAT_X] = {{"lstat_x", 0}}, + [PPME_SYSCALL_FSTAT_E] = {{"fstat_e", 0}}, + [PPME_SYSCALL_FSTAT_X] = {{"fstat_x", 0}}, + [PPME_SYSCALL_LSEEK_E] = {{"lseek_e", 0}}, + [PPME_SYSCALL_LSEEK_X] = {{"lseek_x", 0}}, + [PPME_SYSCALL_LLSEEK_E] = {{"llseek_e", 0}}, + [PPME_SYSCALL_LLSEEK_X] = {{"llseek_x", 0}}, + [PPME_SYSCALL_WRITE_E] = {{"write_e", 0}}, + [PPME_SYSCALL_WRITE_X] = {{"write_x", 0}}, + [PPME_SYSCALL_WRITEV_E] = {{"writev_e", 0}}, + [PPME_SYSCALL_WRITEV_X] = {{"writev_x", 0}}, + [PPME_SYSCALL_PWRITEV_E] = {{"pwritev_e", 0}}, + [PPME_SYSCALL_PWRITEV_X] = {{"pwritev_x", 0}}, + [PPME_SYSCALL_PWRITE_E] = {{"pwrite64_e", 0}}, + [PPME_SYSCALL_PWRITE_X] = {{"pwrite64_x", 0}}, + [PPME_SYSCALL_GETRESGID_E] = {{"getresgid_e", 0}}, + [PPME_SYSCALL_GETRESGID_X] = {{"getresgid_x", 0}}, + [PPME_SYSCALL_CHOWN_E] = {{"chown_e", 0}}, + [PPME_SYSCALL_CHOWN_X] = {{"chown_x", 0}}, + [PPME_SYSCALL_LCHOWN_E] = {{"lchown_e", 0}}, + [PPME_SYSCALL_LCHOWN_X] = {{"lchown_x", 0}}, + [PPME_SYSCALL_FCHOWN_E] = {{"fchown_e", 0}}, + [PPME_SYSCALL_FCHOWN_X] = {{"fchown_x", 0}}, + [PPME_SYSCALL_FCHOWNAT_E] = {{"fchownat_e", 0}}, + [PPME_SYSCALL_FCHOWNAT_X] = {{"fchownat_x", 0}}, + [PPME_SYSCALL_BRK_4_E] = {{"brk_e", 0}}, + [PPME_SYSCALL_BRK_4_X] = {{"brk_x", 0}}, + [PPME_SYSCALL_GETRLIMIT_E] = {{"getrlimit_e", 0}}, + [PPME_SYSCALL_GETRLIMIT_X] = {{"getrlimit_x", 0}}, + [PPME_SOCKET_SEND_E] = {{"send_e", 0}}, + [PPME_SOCKET_SEND_X] = {{"send_x", 0}}, + [PPME_SOCKET_RECV_E] = {{"recv_e", 0}}, + [PPME_SOCKET_RECV_X] = {{"recv_x", 0}}, + [PPME_SYSCALL_NANOSLEEP_E] = {{"nanosleep_e", 0}}, + [PPME_SYSCALL_NANOSLEEP_X] = {{"nanosleep_x", 0}}, + [PPME_SYSCALL_UMOUNT_1_E] = {{"umount_e", 0}}, + [PPME_SYSCALL_UMOUNT_1_X] = {{"umount_x", 0}}, + [PPME_SOCKET_ACCEPT4_6_E] = {{"accept4_e", 0}}, + [PPME_SOCKET_ACCEPT4_6_X] = {{"accept4_x", 0}}, + [PPME_SYSCALL_PIPE2_E] = {{"pipe2_e", 0}}, + [PPME_SYSCALL_PIPE2_X] = {{"pipe2_x", 0}}, + [PPME_SYSCALL_INOTIFY_INIT1_E] = {{"inotify_init1_e", 0}}, + [PPME_SYSCALL_INOTIFY_INIT1_X] = {{"inotify_init1_x", 0}}, + [PPME_SYSCALL_EVENTFD2_E] = {{"eventfd2_e", 0}}, + [PPME_SYSCALL_EVENTFD2_X] = {{"eventfd2_x", 0}}, + [PPME_SYSCALL_SIGNALFD4_E] = {{"signalfd4_e", 0}}, + [PPME_SYSCALL_SIGNALFD4_X] = {{"signalfd4_x", 0}}, + [PPME_SYSCALL_PRCTL_E] = {{"prctl_e", 0}}, + [PPME_SYSCALL_PRCTL_X] = {{"prctl_x", 0}}, + [PPME_SYSCALL_MEMFD_CREATE_E] = {{"memfd_create_e", 0}}, + [PPME_SYSCALL_MEMFD_CREATE_X] = {{"memfd_create_x", 0}}, + [PPME_SYSCALL_PIDFD_GETFD_E] = {{"pidfd_getfd_e", 0}}, + [PPME_SYSCALL_PIDFD_GETFD_X] = {{"pidfd_getfd_x", 0}}, + [PPME_SYSCALL_PIDFD_OPEN_E] = {{"pidfd_open_e", 0}}, + [PPME_SYSCALL_PIDFD_OPEN_X] = {{"pidfd_open_x", 0}}, + [PPME_SYSCALL_INIT_MODULE_E] = {{"init_module_e", 0}}, + [PPME_SYSCALL_INIT_MODULE_X] = {{"init_module_x", 0}}, + [PPME_SYSCALL_FINIT_MODULE_E] = {{"finit_module_e", 0}}, + [PPME_SYSCALL_FINIT_MODULE_X] = {{"finit_module_x", 0}}, + [PPME_SYSCALL_MKNOD_E] = {{"mknod_e", 0}}, + [PPME_SYSCALL_MKNOD_X] = {{"mknod_x", 0}}, + [PPME_SYSCALL_MKNODAT_E] = {{"mknodat_e", 0}}, + [PPME_SYSCALL_MKNODAT_X] = {{"mknodat_x", 0}}, + [PPME_SYSCALL_NEWFSTATAT_E] = {{"newfstatat_e", 0}}, + [PPME_SYSCALL_NEWFSTATAT_X] = {{"newfstatat_x", 0}}, + [PPME_SYSCALL_PROCESS_VM_READV_E] = {{"process_vm_readv_e", 0}}, + [PPME_SYSCALL_PROCESS_VM_READV_X] = {{"process_vm_readv_x", 0}}, + [PPME_SYSCALL_PROCESS_VM_WRITEV_E] = {{"process_vm_writev_e", 0}}, + [PPME_SYSCALL_PROCESS_VM_WRITEV_X] = {{"process_vm_writev_x", 0}}, + [PPME_SYSCALL_DELETE_MODULE_E] = {{"delete_module_e", 0}}, + [PPME_SYSCALL_DELETE_MODULE_X] = {{"delete_module_x", 0}}, + [PPME_SYSCALL_SETREUID_E] = {{"setreuid_e", 0}}, + [PPME_SYSCALL_SETREUID_X] = {{"setreuid_x", 0}}, + [PPME_SYSCALL_SETREGID_E] = {{"setregid_e", 0}}, + [PPME_SYSCALL_SETREGID_X] = {{"setregid_x", 0}}, +}; diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 2aba445b90..523e5ac513 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 /* -Copyright (C) 2023 The Falco Authors. +Copyright (C) 2025 The Falco Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,340 +20,15 @@ limitations under the License. #include #include +#include -/* For every event here we have the name of the corresponding bpf program. */ -static const char* event_prog_names[PPM_EVENT_MAX] = { - [PPME_GENERIC_E] = "generic_e", - [PPME_GENERIC_X] = "generic_x", - [PPME_SYSCALL_GETCWD_E] = "getcwd_e", - [PPME_SYSCALL_GETCWD_X] = "getcwd_x", - [PPME_SYSCALL_GETDENTS_E] = "getdents_e", - [PPME_SYSCALL_GETDENTS_X] = "getdents_x", - [PPME_SYSCALL_GETDENTS64_E] = "getdents64_e", - [PPME_SYSCALL_GETDENTS64_X] = "getdents64_x", - [PPME_SYSCALL_EPOLLWAIT_E] = "epoll_wait_e", - [PPME_SYSCALL_EPOLLWAIT_X] = "epoll_wait_x", - [PPME_SOCKET_GETPEERNAME_E] = "getpeername_e", - [PPME_SOCKET_GETPEERNAME_X] = "getpeername_x", - [PPME_SOCKET_GETSOCKNAME_E] = "getsockname_e", - [PPME_SOCKET_GETSOCKNAME_X] = "getsockname_x", - [PPME_SYSCALL_MKDIR_2_E] = "mkdir_e", - [PPME_SYSCALL_MKDIR_2_X] = "mkdir_x", - [PPME_SYSCALL_MMAP_E] = "mmap_e", - [PPME_SYSCALL_MMAP_X] = "mmap_x", - [PPME_SYSCALL_MUNMAP_E] = "munmap_e", - [PPME_SYSCALL_MUNMAP_X] = "munmap_x", - [PPME_SYSCALL_OPEN_E] = "open_e", - [PPME_SYSCALL_OPEN_X] = "open_x", - [PPME_SYSCALL_OPENAT_2_E] = "openat_e", - [PPME_SYSCALL_OPENAT_2_X] = "openat_x", - [PPME_SYSCALL_OPENAT2_E] = "openat2_e", - [PPME_SYSCALL_OPENAT2_X] = "openat2_x", - [PPME_SYSCALL_OPEN_BY_HANDLE_AT_E] = "open_by_handle_at_e", - [PPME_SYSCALL_OPEN_BY_HANDLE_AT_X] = "open_by_handle_at_x", - [PPME_SYSCALL_CLOSE_E] = "close_e", - [PPME_SYSCALL_CLOSE_X] = "close_x", - [PPME_SYSCALL_COPY_FILE_RANGE_E] = "copy_file_range_e", - [PPME_SYSCALL_COPY_FILE_RANGE_X] = "copy_file_range_x", - [PPME_SYSCALL_CREAT_E] = "creat_e", - [PPME_SYSCALL_CREAT_X] = "creat_x", - [PPME_SYSCALL_DUP_1_E] = "dup_e", - [PPME_SYSCALL_DUP_1_X] = "dup_x", - [PPME_SYSCALL_DUP2_E] = "dup2_e", - [PPME_SYSCALL_DUP2_X] = "dup2_x", - [PPME_SYSCALL_DUP3_E] = "dup3_e", - [PPME_SYSCALL_DUP3_X] = "dup3_x", - [PPME_SYSCALL_CHDIR_E] = "chdir_e", - [PPME_SYSCALL_CHDIR_X] = "chdir_x", - [PPME_SYSCALL_CHMOD_E] = "chmod_e", - [PPME_SYSCALL_CHMOD_X] = "chmod_x", - [PPME_SYSCALL_CHROOT_E] = "chroot_e", - [PPME_SYSCALL_CHROOT_X] = "chroot_x", - [PPME_SYSCALL_FCHDIR_E] = "fchdir_e", - [PPME_SYSCALL_FCHDIR_X] = "fchdir_x", - [PPME_SYSCALL_FCHMOD_E] = "fchmod_e", - [PPME_SYSCALL_FCHMOD_X] = "fchmod_x", - [PPME_SYSCALL_FCHMODAT_E] = "fchmodat_e", - [PPME_SYSCALL_FCHMODAT_X] = "fchmodat_x", - [PPME_SYSCALL_MKDIRAT_E] = "mkdirat_e", - [PPME_SYSCALL_MKDIRAT_X] = "mkdirat_x", - [PPME_SYSCALL_RMDIR_2_E] = "rmdir_e", - [PPME_SYSCALL_RMDIR_2_X] = "rmdir_x", - [PPME_SYSCALL_EVENTFD_E] = "eventfd_e", - [PPME_SYSCALL_EVENTFD_X] = "eventfd_x", - [PPME_SYSCALL_INOTIFY_INIT_E] = "inotify_init_e", - [PPME_SYSCALL_INOTIFY_INIT_X] = "inotify_init_x", - [PPME_SYSCALL_TIMERFD_CREATE_E] = "timerfd_create_e", - [PPME_SYSCALL_TIMERFD_CREATE_X] = "timerfd_create_x", - [PPME_SYSCALL_USERFAULTFD_E] = "userfaultfd_e", - [PPME_SYSCALL_USERFAULTFD_X] = "userfaultfd_x", - [PPME_SYSCALL_SIGNALFD_E] = "signalfd_e", - [PPME_SYSCALL_SIGNALFD_X] = "signalfd_x", - [PPME_SYSCALL_KILL_E] = "kill_e", - [PPME_SYSCALL_KILL_X] = "kill_x", - [PPME_SYSCALL_TGKILL_E] = "tgkill_e", - [PPME_SYSCALL_TGKILL_X] = "tgkill_x", - [PPME_SYSCALL_TKILL_E] = "tkill_e", - [PPME_SYSCALL_TKILL_X] = "tkill_x", - [PPME_SYSCALL_SECCOMP_E] = "seccomp_e", - [PPME_SYSCALL_SECCOMP_X] = "seccomp_x", - [PPME_SYSCALL_PTRACE_E] = "ptrace_e", - [PPME_SYSCALL_PTRACE_X] = "ptrace_x", - [PPME_SYSCALL_CAPSET_E] = "capset_e", - [PPME_SYSCALL_CAPSET_X] = "capset_x", - [PPME_SOCKET_SOCKET_E] = "socket_e", - [PPME_SOCKET_SOCKET_X] = "socket_x", - [PPME_SOCKET_CONNECT_E] = "connect_e", - [PPME_SOCKET_CONNECT_X] = "connect_x", - [PPME_SOCKET_SOCKETPAIR_E] = "socketpair_e", - [PPME_SOCKET_SOCKETPAIR_X] = "socketpair_x", - [PPME_SOCKET_ACCEPT_5_E] = "accept_e", - [PPME_SOCKET_ACCEPT_5_X] = "accept_x", - [PPME_SOCKET_BIND_E] = "bind_e", - [PPME_SOCKET_BIND_X] = "bind_x", - [PPME_SOCKET_LISTEN_E] = "listen_e", - [PPME_SOCKET_LISTEN_X] = "listen_x", - [PPME_SYSCALL_EXECVE_19_E] = "execve_e", - [PPME_SYSCALL_EXECVE_19_X] = "execve_x", - [PPME_SYSCALL_EXECVEAT_E] = "execveat_e", - [PPME_SYSCALL_EXECVEAT_X] = "execveat_x", - [PPME_SYSCALL_CLONE_20_E] = "clone_e", - [PPME_SYSCALL_CLONE_20_X] = "clone_x", - [PPME_SYSCALL_CLONE3_E] = "clone3_e", - [PPME_SYSCALL_CLONE3_X] = "clone3_x", - [PPME_SYSCALL_FORK_20_E] = "fork_e", - [PPME_SYSCALL_FORK_20_X] = "fork_x", - [PPME_SYSCALL_VFORK_20_E] = "vfork_e", - [PPME_SYSCALL_VFORK_20_X] = "vfork_x", - [PPME_SYSCALL_RENAME_E] = "rename_e", - [PPME_SYSCALL_RENAME_X] = "rename_x", - [PPME_SYSCALL_RENAMEAT_E] = "renameat_e", - [PPME_SYSCALL_RENAMEAT_X] = "renameat_x", - [PPME_SYSCALL_RENAMEAT2_E] = "renameat2_e", - [PPME_SYSCALL_RENAMEAT2_X] = "renameat2_x", - [PPME_SYSCALL_PIPE_E] = "pipe_e", - [PPME_SYSCALL_PIPE_X] = "pipe_x", - [PPME_SYSCALL_READV_E] = "readv_e", - [PPME_SYSCALL_READV_X] = "readv_x", - [PPME_SYSCALL_PREADV_E] = "preadv_e", - [PPME_SYSCALL_PREADV_X] = "preadv_x", - [PPME_SYSCALL_PREAD_E] = "pread64_e", - [PPME_SYSCALL_PREAD_X] = "pread64_x", - [PPME_SYSCALL_BPF_2_E] = "bpf_e", - [PPME_SYSCALL_BPF_2_X] = "bpf_x", - [PPME_SYSCALL_FLOCK_E] = "flock_e", - [PPME_SYSCALL_FLOCK_X] = "flock_x", - [PPME_SYSCALL_IOCTL_3_E] = "ioctl_e", - [PPME_SYSCALL_IOCTL_3_X] = "ioctl_x", - [PPME_SYSCALL_QUOTACTL_E] = "quotactl_e", - [PPME_SYSCALL_QUOTACTL_X] = "quotactl_x", - [PPME_SYSCALL_UNSHARE_E] = "unshare_e", - [PPME_SYSCALL_UNSHARE_X] = "unshare_x", - [PPME_SYSCALL_MOUNT_E] = "mount_e", - [PPME_SYSCALL_MOUNT_X] = "mount_x", - [PPME_SYSCALL_UMOUNT2_E] = "umount2_e", - [PPME_SYSCALL_UMOUNT2_X] = "umount2_x", - [PPME_SYSCALL_LINK_2_E] = "link_e", - [PPME_SYSCALL_LINK_2_X] = "link_x", - [PPME_SYSCALL_LINKAT_2_E] = "linkat_e", - [PPME_SYSCALL_LINKAT_2_X] = "linkat_x", - [PPME_SYSCALL_SYMLINK_E] = "symlink_e", - [PPME_SYSCALL_SYMLINK_X] = "symlink_x", - [PPME_SYSCALL_SYMLINKAT_E] = "symlinkat_e", - [PPME_SYSCALL_SYMLINKAT_X] = "symlinkat_x", - [PPME_SYSCALL_UNLINK_2_E] = "unlink_e", - [PPME_SYSCALL_UNLINK_2_X] = "unlink_x", - [PPME_SYSCALL_UNLINKAT_2_E] = "unlinkat_e", - [PPME_SYSCALL_UNLINKAT_2_X] = "unlinkat_x", - [PPME_SYSCALL_SETGID_E] = "setgid_e", - [PPME_SYSCALL_SETGID_X] = "setgid_x", - [PPME_SYSCALL_SETUID_E] = "setuid_e", - [PPME_SYSCALL_SETUID_X] = "setuid_x", - [PPME_SYSCALL_SETNS_E] = "setns_e", - [PPME_SYSCALL_SETNS_X] = "setns_x", - [PPME_SYSCALL_SETPGID_E] = "setpgid_e", - [PPME_SYSCALL_SETPGID_X] = "setpgid_x", - [PPME_SYSCALL_SETRESGID_E] = "setresgid_e", - [PPME_SYSCALL_SETRESGID_X] = "setresgid_x", - [PPME_SYSCALL_SETRESUID_E] = "setresuid_e", - [PPME_SYSCALL_SETRESUID_X] = "setresuid_x", - [PPME_SYSCALL_SETSID_E] = "setsid_e", - [PPME_SYSCALL_SETSID_X] = "setsid_x", - [PPME_SYSCALL_SETRLIMIT_E] = "setrlimit_e", - [PPME_SYSCALL_SETRLIMIT_X] = "setrlimit_x", - [PPME_SYSCALL_PRLIMIT_E] = "prlimit64_e", - [PPME_SYSCALL_PRLIMIT_X] = "prlimit64_x", - [PPME_SOCKET_SETSOCKOPT_E] = "setsockopt_e", - [PPME_SOCKET_SETSOCKOPT_X] = "setsockopt_x", - [PPME_SOCKET_SENDMSG_E] = "sendmsg_e", - [PPME_SOCKET_SENDMSG_X] = "sendmsg_x", - [PPME_SOCKET_SENDTO_E] = "sendto_e", - [PPME_SOCKET_SENDTO_X] = "sendto_x", - [PPME_SOCKET_RECVMSG_E] = "recvmsg_e", - [PPME_SOCKET_RECVMSG_X] = "recvmsg_x", - [PPME_SOCKET_RECVFROM_E] = "recvfrom_e", - [PPME_SOCKET_RECVFROM_X] = "recvfrom_x", - [PPME_SYSCALL_FCNTL_E] = "fcntl_e", - [PPME_SYSCALL_FCNTL_X] = "fcntl_x", - [PPME_SOCKET_SHUTDOWN_E] = "shutdown_e", - [PPME_SOCKET_SHUTDOWN_X] = "shutdown_x", - [PPME_SYSCALL_FSCONFIG_E] = "fsconfig_e", - [PPME_SYSCALL_FSCONFIG_X] = "fsconfig_x", - [PPME_SYSCALL_EPOLL_CREATE_E] = "epoll_create_e", - [PPME_SYSCALL_EPOLL_CREATE_X] = "epoll_create_x", - [PPME_SYSCALL_EPOLL_CREATE1_E] = "epoll_create1_e", - [PPME_SYSCALL_EPOLL_CREATE1_X] = "epoll_create1_x", - [PPME_SYSCALL_ACCESS_E] = "access_e", - [PPME_SYSCALL_ACCESS_X] = "access_x", - [PPME_SOCKET_GETSOCKOPT_E] = "getsockopt_e", - [PPME_SOCKET_GETSOCKOPT_X] = "getsockopt_x", - [PPME_SYSCALL_MPROTECT_E] = "mprotect_e", - [PPME_SYSCALL_MPROTECT_X] = "mprotect_x", - [PPME_SYSCALL_GETUID_E] = "getuid_e", - [PPME_SYSCALL_GETUID_X] = "getuid_x", - [PPME_SYSCALL_GETGID_E] = "getgid_e", - [PPME_SYSCALL_GETGID_X] = "getgid_x", - [PPME_SYSCALL_GETEUID_E] = "geteuid_e", - [PPME_SYSCALL_GETEUID_X] = "geteuid_x", - [PPME_SYSCALL_GETEGID_E] = "getegid_e", - [PPME_SYSCALL_GETEGID_X] = "getegid_x", - [PPME_SYSCALL_MLOCK_E] = "mlock_e", - [PPME_SYSCALL_MLOCK_X] = "mlock_x", - [PPME_SYSCALL_MLOCK2_E] = "mlock2_e", - [PPME_SYSCALL_MLOCK2_X] = "mlock2_x", - [PPME_SYSCALL_MUNLOCK_E] = "munlock_e", - [PPME_SYSCALL_MUNLOCK_X] = "munlock_x", - [PPME_SYSCALL_MLOCKALL_E] = "mlockall_e", - [PPME_SYSCALL_MLOCKALL_X] = "mlockall_x", - [PPME_SYSCALL_MUNLOCKALL_E] = "munlockall_e", - [PPME_SYSCALL_MUNLOCKALL_X] = "munlockall_x", - [PPME_SYSCALL_READ_E] = "read_e", - [PPME_SYSCALL_READ_X] = "read_x", - [PPME_SYSCALL_IO_URING_ENTER_E] = "io_uring_enter_e", - [PPME_SYSCALL_IO_URING_ENTER_X] = "io_uring_enter_x", - [PPME_SYSCALL_IO_URING_REGISTER_E] = "io_uring_register_e", - [PPME_SYSCALL_IO_URING_REGISTER_X] = "io_uring_register_x", - [PPME_SYSCALL_IO_URING_SETUP_E] = "io_uring_setup_e", - [PPME_SYSCALL_IO_URING_SETUP_X] = "io_uring_setup_x", - [PPME_SYSCALL_POLL_E] = "poll_e", - [PPME_SYSCALL_POLL_X] = "poll_x", - [PPME_SYSCALL_PPOLL_E] = "ppoll_e", - [PPME_SYSCALL_PPOLL_X] = "ppoll_x", - [PPME_SYSCALL_MMAP2_E] = "mmap2_e", - [PPME_SYSCALL_MMAP2_X] = "mmap2_x", - [PPME_SYSCALL_SEMGET_E] = "semget_e", - [PPME_SYSCALL_SEMGET_X] = "semget_x", - [PPME_SYSCALL_SEMCTL_E] = "semctl_e", - [PPME_SYSCALL_SEMCTL_X] = "semctl_x", - [PPME_SYSCALL_SELECT_E] = "select_e", - [PPME_SYSCALL_SELECT_X] = "select_x", - [PPME_SYSCALL_SPLICE_E] = "splice_e", - [PPME_SYSCALL_SPLICE_X] = "splice_x", - [PPME_SOCKET_RECVMMSG_E] = "recvmmsg_e", - [PPME_SOCKET_RECVMMSG_X] = "recvmmsg_x", - [PPME_SOCKET_SENDMMSG_E] = "sendmmsg_e", - [PPME_SOCKET_SENDMMSG_X] = "sendmmsg_x", - [PPME_SYSCALL_SEMOP_E] = "semop_e", - [PPME_SYSCALL_SEMOP_X] = "semop_x", - [PPME_SYSCALL_GETRESUID_E] = "getresuid_e", - [PPME_SYSCALL_GETRESUID_X] = "getresuid_x", - [PPME_SYSCALL_SENDFILE_E] = "sendfile_e", - [PPME_SYSCALL_SENDFILE_X] = "sendfile_x", - [PPME_SYSCALL_FUTEX_E] = "futex_e", - [PPME_SYSCALL_FUTEX_X] = "futex_x", - [PPME_SYSCALL_STAT_E] = "stat_e", - [PPME_SYSCALL_STAT_X] = "stat_x", - [PPME_SYSCALL_LSTAT_E] = "lstat_e", - [PPME_SYSCALL_LSTAT_X] = "lstat_x", - [PPME_SYSCALL_FSTAT_E] = "fstat_e", - [PPME_SYSCALL_FSTAT_X] = "fstat_x", - [PPME_SYSCALL_LSEEK_E] = "lseek_e", - [PPME_SYSCALL_LSEEK_X] = "lseek_x", - [PPME_SYSCALL_LLSEEK_E] = "llseek_e", - [PPME_SYSCALL_LLSEEK_X] = "llseek_x", - [PPME_SYSCALL_WRITE_E] = "write_e", - [PPME_SYSCALL_WRITE_X] = "write_x", - [PPME_SYSCALL_WRITEV_E] = "writev_e", - [PPME_SYSCALL_WRITEV_X] = "writev_x", - [PPME_SYSCALL_PWRITEV_E] = "pwritev_e", - [PPME_SYSCALL_PWRITEV_X] = "pwritev_x", - [PPME_SYSCALL_PWRITE_E] = "pwrite64_e", - [PPME_SYSCALL_PWRITE_X] = "pwrite64_x", - [PPME_SYSCALL_GETRESGID_E] = "getresgid_e", - [PPME_SYSCALL_GETRESGID_X] = "getresgid_x", - [PPME_SYSCALL_CHOWN_E] = "chown_e", - [PPME_SYSCALL_CHOWN_X] = "chown_x", - [PPME_SYSCALL_LCHOWN_E] = "lchown_e", - [PPME_SYSCALL_LCHOWN_X] = "lchown_x", - [PPME_SYSCALL_FCHOWN_E] = "fchown_e", - [PPME_SYSCALL_FCHOWN_X] = "fchown_x", - [PPME_SYSCALL_FCHOWNAT_E] = "fchownat_e", - [PPME_SYSCALL_FCHOWNAT_X] = "fchownat_x", - [PPME_SYSCALL_BRK_4_E] = "brk_e", - [PPME_SYSCALL_BRK_4_X] = "brk_x", - [PPME_SYSCALL_GETRLIMIT_E] = "getrlimit_e", - [PPME_SYSCALL_GETRLIMIT_X] = "getrlimit_x", - [PPME_SOCKET_SEND_E] = "send_e", - [PPME_SOCKET_SEND_X] = "send_x", - [PPME_SOCKET_RECV_E] = "recv_e", - [PPME_SOCKET_RECV_X] = "recv_x", - [PPME_SYSCALL_NANOSLEEP_E] = "nanosleep_e", - [PPME_SYSCALL_NANOSLEEP_X] = "nanosleep_x", - [PPME_SYSCALL_UMOUNT_1_E] = "umount_e", - [PPME_SYSCALL_UMOUNT_1_X] = "umount_x", - [PPME_SOCKET_ACCEPT4_6_E] = "accept4_e", - [PPME_SOCKET_ACCEPT4_6_X] = "accept4_x", - [PPME_SYSCALL_PIPE2_E] = "pipe2_e", - [PPME_SYSCALL_PIPE2_X] = "pipe2_x", - [PPME_SYSCALL_INOTIFY_INIT1_E] = "inotify_init1_e", - [PPME_SYSCALL_INOTIFY_INIT1_X] = "inotify_init1_x", - [PPME_SYSCALL_EVENTFD2_E] = "eventfd2_e", - [PPME_SYSCALL_EVENTFD2_X] = "eventfd2_x", - [PPME_SYSCALL_SIGNALFD4_E] = "signalfd4_e", - [PPME_SYSCALL_SIGNALFD4_X] = "signalfd4_x", - [PPME_SYSCALL_PRCTL_E] = "prctl_e", - [PPME_SYSCALL_PRCTL_X] = "prctl_x", - [PPME_SYSCALL_MEMFD_CREATE_E] = "memfd_create_e", - [PPME_SYSCALL_MEMFD_CREATE_X] = "memfd_create_x", - [PPME_SYSCALL_PIDFD_GETFD_E] = "pidfd_getfd_e", - [PPME_SYSCALL_PIDFD_GETFD_X] = "pidfd_getfd_x", - [PPME_SYSCALL_PIDFD_OPEN_E] = "pidfd_open_e", - [PPME_SYSCALL_PIDFD_OPEN_X] = "pidfd_open_x", - [PPME_SYSCALL_INIT_MODULE_E] = "init_module_e", - [PPME_SYSCALL_INIT_MODULE_X] = "init_module_x", - [PPME_SYSCALL_FINIT_MODULE_E] = "finit_module_e", - [PPME_SYSCALL_FINIT_MODULE_X] = "finit_module_x", - [PPME_SYSCALL_MKNOD_E] = "mknod_e", - [PPME_SYSCALL_MKNOD_X] = "mknod_x", - [PPME_SYSCALL_MKNODAT_E] = "mknodat_e", - [PPME_SYSCALL_MKNODAT_X] = "mknodat_x", - [PPME_SYSCALL_NEWFSTATAT_E] = "newfstatat_e", - [PPME_SYSCALL_NEWFSTATAT_X] = "newfstatat_x", - [PPME_SYSCALL_PROCESS_VM_READV_E] = "process_vm_readv_e", - [PPME_SYSCALL_PROCESS_VM_READV_X] = "process_vm_readv_x", - [PPME_SYSCALL_PROCESS_VM_WRITEV_E] = "process_vm_writev_e", - [PPME_SYSCALL_PROCESS_VM_WRITEV_X] = "process_vm_writev_x", - [PPME_SYSCALL_DELETE_MODULE_E] = "delete_module_e", - [PPME_SYSCALL_DELETE_MODULE_X] = "delete_module_x", - [PPME_SYSCALL_SETREUID_E] = "setreuid_e", - [PPME_SYSCALL_SETREUID_X] = "setreuid_x", - [PPME_SYSCALL_SETREGID_E] = "setregid_e", - [PPME_SYSCALL_SETREGID_X] = "setregid_x", -}; +typedef struct { + char* name; + enum bpf_func_id feat; +} event_prog_t; -/* Some exit events can require more than one bpf program to collect all the data. */ -static const char* sys_exit_extra_event_names[SYS_EXIT_EXTRA_CODE_MAX] = { - [T1_EXECVE_X] = "t1_execve_x", - [T1_EXECVEAT_X] = "t1_execveat_x", - [T1_CLONE_X] = "t1_clone_x", - [T1_CLONE3_X] = "t1_clone3_x", - [T1_FORK_X] = "t1_fork_x", - [T1_VFORK_X] = "t1_vfork_x", - [T2_CLONE_X] = "t2_clone_x", - [T2_CLONE3_X] = "t2_clone3_x", - [T2_FORK_X] = "t2_fork_x", - [T2_VFORK_X] = "t2_vfork_x", - [T1_OPEN_BY_HANDLE_AT_X] = "t1_open_by_handle_at_x", - [T2_EXECVE_X] = "t2_execve_x", - [T2_EXECVEAT_X] = "t2_execveat_x", -}; +// Maximum number of programs to be tried (requiring bpf feat checks) for each event +#define MAX_FEATURE_CHECKS 3 + +// Defined in events_prog_names.c +extern event_prog_t event_prog_names[PPM_EVENT_MAX][MAX_FEATURE_CHECKS]; diff --git a/userspace/libpman/src/lifecycle.c b/userspace/libpman/src/lifecycle.c index 51b2950976..bd5661528d 100644 --- a/userspace/libpman/src/lifecycle.c +++ b/userspace/libpman/src/lifecycle.c @@ -18,6 +18,7 @@ limitations under the License. #include "state.h" #include +#include "events_prog_names.h" int pman_open_probe() { g_state.skel = bpf_probe__open(); @@ -28,6 +29,43 @@ int pman_open_probe() { return 0; } +int pman_prepare_progs_before_loading() { + /* + * Probe required features for each bpf program, as requested + */ + for(int ev = 0; ev < PPM_EVENT_MAX; ev++) { + int num_skipped = 0; + int idx = 0; + event_prog_t *progs = event_prog_names[ev]; + for(; idx < MAX_FEATURE_CHECKS && progs[idx].name != NULL; idx++) { + if(progs[idx].feat > 0) { + if(libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) == + 0) { + // Required feature not present + struct bpf_program *p = + bpf_object__find_program_by_name(g_state.skel->obj, progs[idx].name); + if(p) { + bpf_program__set_autoload(p, false); + } else { + pman_print_error(" unable to find prog"); + } + num_skipped++; + } + } + } + if(num_skipped > 0) { + if(num_skipped == idx) { + pman_print_error(" no program satisfied required features for event"); + errno = ENXIO; + return errno; + } + // Store selected program in index 0 to be easily accessed by maps.c + progs[0] = progs[num_skipped]; + } + } + return 0; +} + static void pman_save_attached_progs() { g_state.attached_progs_fds[0] = bpf_program__fd(g_state.skel->progs.sys_enter); g_state.attached_progs_fds[1] = bpf_program__fd(g_state.skel->progs.sys_exit); diff --git a/userspace/libpman/src/maps.c b/userspace/libpman/src/maps.c index 36cb2c0829..ca6ce8e3d3 100644 --- a/userspace/libpman/src/maps.c +++ b/userspace/libpman/src/maps.c @@ -22,6 +22,23 @@ limitations under the License. #include "events_prog_names.h" #include +/* Some exit events can require more than one bpf program to collect all the data. */ +static const char* sys_exit_extra_event_names[SYS_EXIT_EXTRA_CODE_MAX] = { + [T1_EXECVE_X] = "t1_execve_x", + [T1_EXECVEAT_X] = "t1_execveat_x", + [T1_CLONE_X] = "t1_clone_x", + [T1_CLONE3_X] = "t1_clone3_x", + [T1_FORK_X] = "t1_fork_x", + [T1_VFORK_X] = "t1_vfork_x", + [T2_CLONE_X] = "t2_clone_x", + [T2_CLONE3_X] = "t2_clone3_x", + [T2_FORK_X] = "t2_fork_x", + [T2_VFORK_X] = "t2_vfork_x", + [T1_OPEN_BY_HANDLE_AT_X] = "t1_open_by_handle_at_x", + [T2_EXECVE_X] = "t2_execve_x", + [T2_EXECVEAT_X] = "t2_execveat_x", +}; + extern const struct ppm_event_info g_event_info[PPM_EVENT_MAX]; extern const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE]; extern const int g_ia32_64_map[]; @@ -220,15 +237,15 @@ int pman_fill_syscalls_tail_table() { * event. Until we miss some syscalls, this is not true so we manage these cases as generic * events. We need to remove this workaround when all syscalls will be implemented. */ - enter_prog_name = event_prog_names[enter_event_type]; - exit_prog_name = event_prog_names[exit_event_type]; + enter_prog_name = event_prog_names[enter_event_type]->name; + exit_prog_name = event_prog_names[exit_event_type]->name; if(!enter_prog_name) { - enter_prog_name = event_prog_names[PPME_GENERIC_E]; + enter_prog_name = event_prog_names[PPME_GENERIC_E]->name; } if(!exit_prog_name) { - exit_prog_name = event_prog_names[PPME_GENERIC_X]; + exit_prog_name = event_prog_names[PPME_GENERIC_X]->name; } if(add_bpf_program_to_tail_table(syscall_enter_tail_table_fd, diff --git a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c index 55b4876385..1d57b022e3 100644 --- a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c +++ b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c @@ -264,6 +264,7 @@ int32_t scap_modern_bpf__init(scap_t* handle, scap_open_args* oargs) { ret = pman_open_probe(); ret = ret ?: pman_prepare_ringbuf_array_before_loading(); ret = ret ?: pman_prepare_maps_before_loading(); + ret = ret ?: pman_prepare_progs_before_loading(); ret = ret ?: pman_load_probe(); ret = ret ?: pman_finalize_maps_after_loading(); ret = ret ?: pman_finalize_ringbuf_array_after_loading(); From d4e2e2aae24da78c2d85c1b75ebb84d53c7a4f9b Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Fri, 24 Jan 2025 16:52:42 +0100 Subject: [PATCH 2/9] chore(ci): fix s390x drivers ci by symlimking libbpf headers. Signed-off-by: Federico Di Pierro --- .github/workflows/drivers_ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/drivers_ci.yml b/.github/workflows/drivers_ci.yml index 62a3b8f246..1c017efa2e 100644 --- a/.github/workflows/drivers_ci.yml +++ b/.github/workflows/drivers_ci.yml @@ -220,8 +220,9 @@ jobs: cd src && make install cd ../../ git clone https://github.com/libbpf/libbpf.git --branch v1.3.0 --single-branch - cd libbpf/src && BUILD_STATIC_ONLY=y DESTDIR=/ make install + cd libbpf/src && BUILD_STATIC_ONLY=y DESTDIR=/ make install install_uapi_headers ln -s /usr/lib64/libbpf.a /usr/lib/s390x-linux-gnu/ + ln -s /usr/include/bpf /usr/include/s390x-linux-gnu/ # Please note: we cannot inject the BPF probe inside QEMU, so right now, we only build it run: | git config --global --add safe.directory $GITHUB_WORKSPACE From ffb120773ae40348214f432cb2f5476eb0faf93d Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Fri, 31 Jan 2025 09:11:42 +0100 Subject: [PATCH 3/9] chore(userspace/libpman): some renamings to better reflect new changes. Signed-off-by: Federico Di Pierro --- userspace/libpman/CMakeLists.txt | 2 +- .../src/{events_prog_names.c => events_prog_table.c} | 4 ++-- .../src/{events_prog_names.h => events_prog_table.h} | 2 +- userspace/libpman/src/lifecycle.c | 6 +++--- userspace/libpman/src/maps.c | 10 +++++----- 5 files changed, 12 insertions(+), 12 deletions(-) rename userspace/libpman/src/{events_prog_names.c => events_prog_table.c} (99%) rename userspace/libpman/src/{events_prog_names.h => events_prog_table.h} (93%) diff --git a/userspace/libpman/CMakeLists.txt b/userspace/libpman/CMakeLists.txt index 0b8dd4b9b0..55e1126e66 100644 --- a/userspace/libpman/CMakeLists.txt +++ b/userspace/libpman/CMakeLists.txt @@ -27,7 +27,7 @@ add_library( src/configuration.c src/state.c src/sc_set.c - src/events_prog_names.c + src/events_prog_table.c ) target_include_directories( diff --git a/userspace/libpman/src/events_prog_names.c b/userspace/libpman/src/events_prog_table.c similarity index 99% rename from userspace/libpman/src/events_prog_names.c rename to userspace/libpman/src/events_prog_table.c index 4ec640fb4b..61c3dd1358 100644 --- a/userspace/libpman/src/events_prog_names.c +++ b/userspace/libpman/src/events_prog_table.c @@ -16,13 +16,13 @@ limitations under the License. */ -#include "events_prog_names.h" +#include "events_prog_table.h" /* * For every event here we have the name of the corresponding bpf program. * We can have multiple names in case we need to check the right program * that needs to be loaded, eg: because of different bpf features. */ -event_prog_t event_prog_names[PPM_EVENT_MAX][MAX_FEATURE_CHECKS] = { +event_prog_t event_prog_table[PPM_EVENT_MAX][MAX_FEATURE_CHECKS] = { [PPME_GENERIC_E] = {{"generic_e", 0}}, [PPME_GENERIC_X] = {{"generic_x", 0}}, [PPME_SYSCALL_GETCWD_E] = {{"getcwd_e", 0}}, diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_table.h similarity index 93% rename from userspace/libpman/src/events_prog_names.h rename to userspace/libpman/src/events_prog_table.h index 523e5ac513..b435b0be56 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_table.h @@ -31,4 +31,4 @@ typedef struct { #define MAX_FEATURE_CHECKS 3 // Defined in events_prog_names.c -extern event_prog_t event_prog_names[PPM_EVENT_MAX][MAX_FEATURE_CHECKS]; +extern event_prog_t event_prog_table[PPM_EVENT_MAX][MAX_FEATURE_CHECKS]; diff --git a/userspace/libpman/src/lifecycle.c b/userspace/libpman/src/lifecycle.c index bd5661528d..1d0c5a8ad1 100644 --- a/userspace/libpman/src/lifecycle.c +++ b/userspace/libpman/src/lifecycle.c @@ -18,7 +18,7 @@ limitations under the License. #include "state.h" #include -#include "events_prog_names.h" +#include "events_prog_table.h" int pman_open_probe() { g_state.skel = bpf_probe__open(); @@ -36,7 +36,7 @@ int pman_prepare_progs_before_loading() { for(int ev = 0; ev < PPM_EVENT_MAX; ev++) { int num_skipped = 0; int idx = 0; - event_prog_t *progs = event_prog_names[ev]; + event_prog_t *progs = event_prog_table[ev]; for(; idx < MAX_FEATURE_CHECKS && progs[idx].name != NULL; idx++) { if(progs[idx].feat > 0) { if(libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) == @@ -55,7 +55,7 @@ int pman_prepare_progs_before_loading() { } if(num_skipped > 0) { if(num_skipped == idx) { - pman_print_error(" no program satisfied required features for event"); + pman_print_error(" no program satisfies required features for event"); errno = ENXIO; return errno; } diff --git a/userspace/libpman/src/maps.c b/userspace/libpman/src/maps.c index ca6ce8e3d3..8151b19d8f 100644 --- a/userspace/libpman/src/maps.c +++ b/userspace/libpman/src/maps.c @@ -19,7 +19,7 @@ limitations under the License. #include "state.h" #include -#include "events_prog_names.h" +#include "events_prog_table.h" #include /* Some exit events can require more than one bpf program to collect all the data. */ @@ -237,15 +237,15 @@ int pman_fill_syscalls_tail_table() { * event. Until we miss some syscalls, this is not true so we manage these cases as generic * events. We need to remove this workaround when all syscalls will be implemented. */ - enter_prog_name = event_prog_names[enter_event_type]->name; - exit_prog_name = event_prog_names[exit_event_type]->name; + enter_prog_name = event_prog_table[enter_event_type]->name; + exit_prog_name = event_prog_table[exit_event_type]->name; if(!enter_prog_name) { - enter_prog_name = event_prog_names[PPME_GENERIC_E]->name; + enter_prog_name = event_prog_table[PPME_GENERIC_E]->name; } if(!exit_prog_name) { - exit_prog_name = event_prog_names[PPME_GENERIC_X]->name; + exit_prog_name = event_prog_table[PPME_GENERIC_X]->name; } if(add_bpf_program_to_tail_table(syscall_enter_tail_table_fd, From 57280e181363a2bd5f040587cb79bc86116e3c93 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 3 Feb 2025 11:02:06 +0100 Subject: [PATCH 4/9] chore(driver/modern_ebpf): avoid passing unused data to bpf_loop callback. Signed-off-by: Federico Di Pierro --- .../events/syscall_dispatched_events/recvmmsg.bpf.c | 3 --- .../events/syscall_dispatched_events/sendmmsg.bpf.c | 11 ++--------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c index f0a2021fb5..0cf8174eb1 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c @@ -39,7 +39,6 @@ typedef struct { uint32_t fd; struct mmsghdr *mmh; struct pt_regs *regs; - void *ctx; } recvmmsg_data_t; static __always_inline long handle_exit(uint32_t index, void *ctx) { @@ -156,7 +155,6 @@ int BPF_PROG(recvmmsg_x, struct pt_regs *regs, long ret) { .fd = args[0], .mmh = (struct mmsghdr *)args[1], .regs = regs, - .ctx = ctx, }; uint32_t nr_loops = ret < 1024 ? ret : 1024; @@ -208,7 +206,6 @@ int BPF_PROG(recvmmsg_old_x, struct pt_regs *regs, long ret) { .fd = args[0], .mmh = (struct mmsghdr *)args[1], .regs = regs, - .ctx = ctx, }; // Send only first message diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c index e69750cd76..6cd0f21bd6 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c @@ -39,7 +39,6 @@ typedef struct { uint32_t fd; struct mmsghdr *mmh; struct pt_regs *regs; - void *ctx; } sendmmsg_exit_t; static __always_inline long handle_exit(uint32_t index, void *ctx) { @@ -89,18 +88,14 @@ static __always_inline long handle_exit(uint32_t index, void *ctx) { } /* Parameter 4: data (type: PT_BYTEBUF) */ - unsigned long msghdr_pointer = (unsigned long)&mmh.msg_hdr; auxmap__store_iovec_data_param(auxmap, (unsigned long)mmh.msg_hdr.msg_iov, mmh.msg_hdr.msg_iovlen, snaplen); /* Parameter 5: tuple (type: PT_SOCKTUPLE)*/ - if(data->fd >= 0) { - auxmap__store_socktuple_param(auxmap, data->fd, OUTBOUND, mmh.msg_hdr.msg_name); - } else { - auxmap__store_empty_param(auxmap); - } + auxmap__store_socktuple_param(auxmap, data->fd, OUTBOUND, mmh.msg_hdr.msg_name); + /*=============================== COLLECT PARAMETERS ===========================*/ auxmap__finalize_event_header(auxmap); @@ -149,7 +144,6 @@ int BPF_PROG(sendmmsg_x, struct pt_regs *regs, long ret) { .fd = args[0], .mmh = (struct mmsghdr *)args[1], .regs = regs, - .ctx = ctx, }; uint32_t nr_loops = ret < 1024 ? ret : 1024; @@ -198,7 +192,6 @@ int BPF_PROG(sendmmsg_old_x, struct pt_regs *regs, long ret) { .fd = args[0], .mmh = (struct mmsghdr *)args[1], .regs = regs, - .ctx = ctx, }; // Only first message From 7edb2f5bdd0052acf89d0f39cb3c5b59b4ea69e9 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 3 Feb 2025 11:26:11 +0100 Subject: [PATCH 5/9] fix(driver/modern_bpf): avoid referencing out of scope variables. Signed-off-by: Federico Di Pierro --- .../helpers/store/auxmap_store_params.h | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index fca2508c2d..e79bda6055 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -676,6 +676,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * switch(socket_family) { case AF_INET: { struct inet_sock *inet = (struct inet_sock *)sk; + struct sockaddr_in usrsockaddr_in = {}; uint32_t ipv4_local = 0; uint16_t port_local = 0; @@ -690,7 +691,6 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * * of an UDP connection). We fallback to the address from userspace when the kernel-provided * address is NULL */ if(port_remote == 0 && usrsockaddr != NULL) { - struct sockaddr_in usrsockaddr_in = {}; bpf_probe_read_user(&usrsockaddr_in, bpf_core_type_size(struct sockaddr_in), (void *)usrsockaddr); @@ -725,6 +725,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * case AF_INET6: { struct inet_sock *inet = (struct inet_sock *)sk; + struct sockaddr_in6 usrsockaddr_in6 = {}; uint32_t ipv6_local[4] = {0, 0, 0, 0}; uint16_t port_local = 0; @@ -740,7 +741,6 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * * of an UDP connection). We fallback to the address from userspace when the kernel-provided * address is NULL */ if(port_remote == 0 && usrsockaddr != NULL) { - struct sockaddr_in6 usrsockaddr_in6 = {}; bpf_probe_read_user(&usrsockaddr_in6, bpf_core_type_size(struct sockaddr_in6), (void *)usrsockaddr); @@ -1556,6 +1556,13 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, */ unsigned long args[5] = {0}; struct sockaddr *sockaddr = NULL; + typedef union { + struct compat_msghdr compat_mh; + struct user_msghdr mh; + struct compat_mmsghdr compat_mmh; + struct mmsghdr mmh; + } mh_t; + mh_t msg_mh = {}; switch(input_args->evt_type) { case PPME_SOCKET_SENDTO_X: @@ -1568,19 +1575,18 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, case PPME_SOCKET_SENDMSG_X: { extract__network_args(args, 3, regs); if(bpf_in_ia32_syscall()) { - struct compat_msghdr compat_mh = {}; - if(likely(bpf_probe_read_user(&compat_mh, + if(likely(bpf_probe_read_user(&msg_mh.compat_mh, bpf_core_type_size(struct compat_msghdr), (void *)args[1]) == 0)) { - sockaddr = (struct sockaddr *)(unsigned long)(compat_mh.msg_name); + sockaddr = (struct sockaddr *)(unsigned long)(msg_mh.compat_mh.msg_name); } // in any case we break the switch. break; } - - struct user_msghdr mh = {}; - if(bpf_probe_read_user(&mh, bpf_core_type_size(struct user_msghdr), (void *)args[1]) == 0) { - sockaddr = (struct sockaddr *)mh.msg_name; + if(bpf_probe_read_user(&msg_mh.mh, + bpf_core_type_size(struct user_msghdr), + (void *)args[1]) == 0) { + sockaddr = (struct sockaddr *)msg_mh.mh.msg_name; } } break; @@ -1588,23 +1594,20 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, case PPME_SOCKET_SENDMMSG_X: { extract__network_args(args, 3, regs); if(bpf_in_ia32_syscall()) { - struct compat_mmsghdr compat_mmh = {}; struct compat_mmsghdr *mmh_ptr = (struct compat_mmsghdr *)args[1]; - if(likely(bpf_probe_read_user(&compat_mmh, + if(likely(bpf_probe_read_user(&msg_mh.compat_mmh, bpf_core_type_size(struct compat_mmsghdr), (void *)(mmh_ptr + input_args->mmsg_index)) == 0)) { - sockaddr = (struct sockaddr *)(unsigned long)(compat_mmh.msg_hdr.msg_name); + sockaddr = (struct sockaddr *)(unsigned long)(msg_mh.compat_mmh.msg_hdr.msg_name); } // in any case we break the switch. break; } - - struct mmsghdr mmh = {}; struct mmsghdr *mmh_ptr = (struct mmsghdr *)args[1]; - if(bpf_probe_read_user(&mmh, + if(bpf_probe_read_user(&msg_mh.mmh, bpf_core_type_size(struct mmsghdr), (void *)(mmh_ptr + input_args->mmsg_index)) == 0) { - sockaddr = (struct sockaddr *)mmh.msg_hdr.msg_name; + sockaddr = (struct sockaddr *)msg_mh.mmh.msg_hdr.msg_name; } } break; From 3ab30fc00594a7c62883a724e476e1c5bd338ddb Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 3 Feb 2025 15:10:22 +0100 Subject: [PATCH 6/9] fix(driver/modern_bpf): avoid calling `extract_network_args` in apply_dynamic_snaplen at each bpf_loop iteration for sendmmsg and recvmmsg. This also fixes a verifier issue on clang 14, related to stack length. Signed-off-by: Federico Di Pierro --- .../helpers/store/auxmap_store_params.h | 27 +++++++++++++------ .../syscall_dispatched_events/recvmmsg.bpf.c | 17 ++++++------ .../syscall_dispatched_events/sendmmsg.bpf.c | 17 ++++++------ 3 files changed, 37 insertions(+), 24 deletions(-) diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index e79bda6055..8f65424697 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -1506,7 +1506,9 @@ static __always_inline void auxmap__store_fdlist_param(struct auxiliary_map *aux typedef struct { bool only_port_range; ppm_event_code evt_type; - long mmsg_index; + long mmsg_index; // Only used by sendmmsg/recvmmsg to pass the current message index + unsigned long *mm_args; // Only used by sendmmsg/recvmmsg to reduce stack size to avoid + // verifier issues } dynamic_snaplen_args; static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, @@ -1592,7 +1594,11 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, case PPME_SOCKET_RECVMMSG_X: case PPME_SOCKET_SENDMMSG_X: { - extract__network_args(args, 3, regs); + // To avoid verifier stack size issues, sendmmsg and recvmmsg directly pass args + // in dynamic_snaplen_args. + // This also gives a small perf boost while using `bpf_loop` because we don't need + // to re-fetch first 3 syscall args at every iteration. + __builtin_memcpy(args, input_args->mm_args, 3 * sizeof(unsigned long)); if(bpf_in_ia32_syscall()) { struct compat_mmsghdr *mmh_ptr = (struct compat_mmsghdr *)args[1]; if(likely(bpf_probe_read_user(&msg_mh.compat_mmh, @@ -1645,16 +1651,21 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, port_remote = ntohs(port_remote); if(port_remote == 0 && sockaddr != NULL) { + typedef union { + struct sockaddr_in sockaddr_in; + struct sockaddr_in6 sockaddr_in6; + } sa_t; + sa_t saddr_in = {}; if(socket_family == AF_INET) { - struct sockaddr_in sockaddr_in = {}; - bpf_probe_read_user(&sockaddr_in, bpf_core_type_size(struct sockaddr_in), sockaddr); - port_remote = ntohs(sockaddr_in.sin_port); + bpf_probe_read_user(&saddr_in.sockaddr_in, + bpf_core_type_size(struct sockaddr_in), + sockaddr); + port_remote = ntohs(saddr_in.sockaddr_in.sin_port); } else { - struct sockaddr_in6 sockaddr_in6 = {}; - bpf_probe_read_user(&sockaddr_in6, + bpf_probe_read_user(&saddr_in.sockaddr_in6, bpf_core_type_size(struct sockaddr_in6), sockaddr); - port_remote = ntohs(sockaddr_in6.sin6_port); + port_remote = ntohs(saddr_in.sockaddr_in6.sin6_port); } } } diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c index 0cf8174eb1..ddcea0b102 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/recvmmsg.bpf.c @@ -38,7 +38,7 @@ int BPF_PROG(recvmmsg_e, struct pt_regs *regs, long id) { typedef struct { uint32_t fd; struct mmsghdr *mmh; - struct pt_regs *regs; + unsigned long *args; } recvmmsg_data_t; static __always_inline long handle_exit(uint32_t index, void *ctx) { @@ -75,9 +75,10 @@ static __always_inline long handle_exit(uint32_t index, void *ctx) { .only_port_range = true, .evt_type = PPME_SOCKET_RECVMMSG_X, .mmsg_index = index, + .mm_args = data->args, }; uint16_t snaplen = maps__get_snaplen(); - apply_dynamic_snaplen(data->regs, &snaplen, &snaplen_args); + apply_dynamic_snaplen(NULL, &snaplen, &snaplen_args); if(snaplen > mmh.msg_len) { snaplen = mmh.msg_len; } @@ -149,12 +150,12 @@ int BPF_PROG(recvmmsg_x, struct pt_regs *regs, long ret) { } /* Collect parameters at the beginning to manage socketcalls */ - unsigned long args[2]; - extract__network_args(args, 2, regs); + unsigned long args[3]; + extract__network_args(args, 3, regs); recvmmsg_data_t data = { .fd = args[0], .mmh = (struct mmsghdr *)args[1], - .regs = regs, + .args = args, }; uint32_t nr_loops = ret < 1024 ? ret : 1024; @@ -200,12 +201,12 @@ int BPF_PROG(recvmmsg_old_x, struct pt_regs *regs, long ret) { } /* Collect parameters at the beginning to manage socketcalls */ - unsigned long args[2]; - extract__network_args(args, 2, regs); + unsigned long args[3]; + extract__network_args(args, 3, regs); recvmmsg_data_t data = { .fd = args[0], .mmh = (struct mmsghdr *)args[1], - .regs = regs, + .args = args, }; // Send only first message diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c index 6cd0f21bd6..ef1793f9e5 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/sendmmsg.bpf.c @@ -38,7 +38,7 @@ int BPF_PROG(sendmmsg_e, struct pt_regs *regs, long id) { typedef struct { uint32_t fd; struct mmsghdr *mmh; - struct pt_regs *regs; + unsigned long *args; } sendmmsg_exit_t; static __always_inline long handle_exit(uint32_t index, void *ctx) { @@ -80,9 +80,10 @@ static __always_inline long handle_exit(uint32_t index, void *ctx) { .only_port_range = true, .evt_type = PPME_SOCKET_SENDMMSG_X, .mmsg_index = index, + .mm_args = data->args, }; uint16_t snaplen = maps__get_snaplen(); - apply_dynamic_snaplen(data->regs, &snaplen, &snaplen_args); + apply_dynamic_snaplen(NULL, &snaplen, &snaplen_args); if(mmh.msg_len > 0 && snaplen > mmh.msg_len) { snaplen = mmh.msg_len; } @@ -138,12 +139,12 @@ int BPF_PROG(sendmmsg_x, struct pt_regs *regs, long ret) { } /* Collect parameters at the beginning to manage socketcalls */ - unsigned long args[2]; - extract__network_args(args, 2, regs); + unsigned long args[3]; + extract__network_args(args, 3, regs); sendmmsg_exit_t data = { .fd = args[0], .mmh = (struct mmsghdr *)args[1], - .regs = regs, + .args = args, }; uint32_t nr_loops = ret < 1024 ? ret : 1024; @@ -186,12 +187,12 @@ int BPF_PROG(sendmmsg_old_x, struct pt_regs *regs, long ret) { } /* Collect parameters at the beginning to manage socketcalls */ - unsigned long args[2]; - extract__network_args(args, 2, regs); + unsigned long args[3]; + extract__network_args(args, 3, regs); sendmmsg_exit_t data = { .fd = args[0], .mmh = (struct mmsghdr *)args[1], - .regs = regs, + .args = args, }; // Only first message From acbd21c5ffa63dc9bb19c3e03dd3eada285f7567 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 3 Feb 2025 15:44:01 +0100 Subject: [PATCH 7/9] chore(ci): run arm64 driverkit workflow on arm64 runner. Signed-off-by: Federico Di Pierro --- .github/workflows/driverkit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/driverkit.yml b/.github/workflows/driverkit.yml index 26753bf0a4..c6d1f244af 100644 --- a/.github/workflows/driverkit.yml +++ b/.github/workflows/driverkit.yml @@ -55,7 +55,7 @@ jobs: kernelrelease: 6.4.1-1.el9.elrepo.aarch64 target: centos kernelurls: https://download.falco.org/fixtures/libs/kernel-ml-devel-6.4.1-1.el9.elrepo.aarch64.rpm - runs-on: ubuntu-latest + runs-on: ubuntu-24.04-arm container: image: falcosecurity/driverkit:latest steps: From 7c19adb9c7afe3a054c0e5c7db235da6e093877b Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 5 Feb 2025 09:22:29 +0100 Subject: [PATCH 8/9] chore(driver/modern_bpf,userspace/libpman): address review comments. Use anonymous unions in modern bpf driver. Moreover, add some debug prints to `pman_prepare_progs_before_loading`, and always disable all unused programs autoload. Signed-off-by: Federico Di Pierro Co-authored-by: Mauro Ezequiel Moltrasio --- .../helpers/store/auxmap_store_params.h | 10 +-- userspace/libpman/src/lifecycle.c | 83 ++++++++++++++----- userspace/libpman/src/maps.c | 2 +- .../libscap/examples/01-open/scap_open.c | 4 +- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index 8f65424697..7c77b1ee61 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -1558,13 +1558,12 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, */ unsigned long args[5] = {0}; struct sockaddr *sockaddr = NULL; - typedef union { + union { struct compat_msghdr compat_mh; struct user_msghdr mh; struct compat_mmsghdr compat_mmh; struct mmsghdr mmh; - } mh_t; - mh_t msg_mh = {}; + } msg_mh = {}; switch(input_args->evt_type) { case PPME_SOCKET_SENDTO_X: @@ -1651,11 +1650,10 @@ static __always_inline void apply_dynamic_snaplen(struct pt_regs *regs, port_remote = ntohs(port_remote); if(port_remote == 0 && sockaddr != NULL) { - typedef union { + union { struct sockaddr_in sockaddr_in; struct sockaddr_in6 sockaddr_in6; - } sa_t; - sa_t saddr_in = {}; + } saddr_in = {}; if(socket_family == AF_INET) { bpf_probe_read_user(&saddr_in.sockaddr_in, bpf_core_type_size(struct sockaddr_in), diff --git a/userspace/libpman/src/lifecycle.c b/userspace/libpman/src/lifecycle.c index 1d0c5a8ad1..8056252832 100644 --- a/userspace/libpman/src/lifecycle.c +++ b/userspace/libpman/src/lifecycle.c @@ -30,38 +30,77 @@ int pman_open_probe() { } int pman_prepare_progs_before_loading() { + char msg[MAX_ERROR_MESSAGE_LEN]; /* * Probe required features for each bpf program, as requested */ + errno = 0; for(int ev = 0; ev < PPM_EVENT_MAX; ev++) { - int num_skipped = 0; - int idx = 0; event_prog_t *progs = event_prog_table[ev]; - for(; idx < MAX_FEATURE_CHECKS && progs[idx].name != NULL; idx++) { - if(progs[idx].feat > 0) { - if(libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) == - 0) { + int idx, chosen_idx = -1; + for(idx = 0; idx < MAX_FEATURE_CHECKS && progs[idx].name != NULL; idx++) { + bool should_disable = chosen_idx != -1; + if(!should_disable) { + if(progs[idx].feat > 0 && + libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) == + 0) { + snprintf(msg, + MAX_ERROR_MESSAGE_LEN, + "BPF program '%s' did not satisfy required feature [%d]", + progs[idx].name, + progs[idx].feat); + pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg); // Required feature not present - struct bpf_program *p = - bpf_object__find_program_by_name(g_state.skel->obj, progs[idx].name); - if(p) { - bpf_program__set_autoload(p, false); - } else { - pman_print_error(" unable to find prog"); - } - num_skipped++; + should_disable = true; + } else { + // We satified requested feature + snprintf(msg, + MAX_ERROR_MESSAGE_LEN, + "BPF program '%s' satisfied required feature [%d]", + progs[idx].name, + progs[idx].feat); + pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg); + chosen_idx = idx; } } - } - if(num_skipped > 0) { - if(num_skipped == idx) { - pman_print_error(" no program satisfies required features for event"); - errno = ENXIO; - return errno; + + // Disable autoloading for all programs except chosen one + if(should_disable) { + snprintf(msg, MAX_ERROR_MESSAGE_LEN, "disabling BPF program '%s'", progs[idx].name); + pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg); + struct bpf_program *p = + bpf_object__find_program_by_name(g_state.skel->obj, progs[idx].name); + if(p && bpf_program__set_autoload(p, false) == 0) { + snprintf(msg, + MAX_ERROR_MESSAGE_LEN, + "disabled BPF program '%s'", + progs[idx].name); + pman_print_msg(FALCOSECURITY_LOG_SEV_DEBUG, (const char *)msg); + } else { + snprintf(msg, + MAX_ERROR_MESSAGE_LEN, + "failed to disable prog '%s'", + progs[idx].name); + pman_print_error(msg); + } } - // Store selected program in index 0 to be easily accessed by maps.c - progs[0] = progs[num_skipped]; } + + // In case we couldn't find any program satisfying required features, give an error. + // As of today, this will never happen, but better safe than sorry. + if(chosen_idx == -1 && progs[0].name != NULL) { + snprintf(msg, + MAX_ERROR_MESSAGE_LEN, + "no program satisfies required features for event %d", + ev); + pman_print_error(msg); + errno = ENXIO; + return errno; + } + + // Always move the selected program to index 0 to be easily accessed by maps.c + // If no programs are skipped, the following line expands to progs[0] = progs[0]; + progs[0] = progs[chosen_idx]; } return 0; } diff --git a/userspace/libpman/src/maps.c b/userspace/libpman/src/maps.c index 8151b19d8f..bb47ab143b 100644 --- a/userspace/libpman/src/maps.c +++ b/userspace/libpman/src/maps.c @@ -307,7 +307,7 @@ static int size_auxiliary_maps() { static int size_counter_maps() { /* We always allocate counter maps from all the CPUs, even if some of them are not online. */ if(bpf_map__set_max_entries(g_state.skel->maps.counter_maps, g_state.n_possible_cpus)) { - pman_print_error(" unable to set max entries for 'counter_maps'"); + pman_print_error("unable to set max entries for 'counter_maps'"); return errno; } return 0; diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 0024747bfa..903be3126b 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -645,10 +645,10 @@ void scap_open_log_fn(const char* component, const enum falcosecurity_log_severity sev) { if(sev <= severity_level) { if(component != NULL) { - printf("%s: %s", component, msg); + printf("%s: %s\n", component, msg); } else { // libbpf logs have no components - printf("%s", msg); + printf("%s\n", msg); } } } From 3e0e122497898d9e72cb00c2de3941443ca9d957 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 6 Feb 2025 08:46:24 +0100 Subject: [PATCH 9/9] chore(driver/modern_bpf,userspace/libpman): properly use `BPF_PROG_TYPE_TRACING` in `pman_prepare_progs_before_loading`. Signed-off-by: Federico Di Pierro Co-authored-by: Andrea Terzolo --- driver/modern_bpf/helpers/store/auxmap_store_params.h | 4 ++-- userspace/libpman/src/lifecycle.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/driver/modern_bpf/helpers/store/auxmap_store_params.h b/driver/modern_bpf/helpers/store/auxmap_store_params.h index 7c77b1ee61..d6cbe663e0 100644 --- a/driver/modern_bpf/helpers/store/auxmap_store_params.h +++ b/driver/modern_bpf/helpers/store/auxmap_store_params.h @@ -676,7 +676,6 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * switch(socket_family) { case AF_INET: { struct inet_sock *inet = (struct inet_sock *)sk; - struct sockaddr_in usrsockaddr_in = {}; uint32_t ipv4_local = 0; uint16_t port_local = 0; @@ -691,6 +690,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * * of an UDP connection). We fallback to the address from userspace when the kernel-provided * address is NULL */ if(port_remote == 0 && usrsockaddr != NULL) { + struct sockaddr_in usrsockaddr_in = {}; bpf_probe_read_user(&usrsockaddr_in, bpf_core_type_size(struct sockaddr_in), (void *)usrsockaddr); @@ -725,7 +725,6 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * case AF_INET6: { struct inet_sock *inet = (struct inet_sock *)sk; - struct sockaddr_in6 usrsockaddr_in6 = {}; uint32_t ipv6_local[4] = {0, 0, 0, 0}; uint16_t port_local = 0; @@ -741,6 +740,7 @@ static __always_inline void auxmap__store_socktuple_param(struct auxiliary_map * * of an UDP connection). We fallback to the address from userspace when the kernel-provided * address is NULL */ if(port_remote == 0 && usrsockaddr != NULL) { + struct sockaddr_in6 usrsockaddr_in6 = {}; bpf_probe_read_user(&usrsockaddr_in6, bpf_core_type_size(struct sockaddr_in6), (void *)usrsockaddr); diff --git a/userspace/libpman/src/lifecycle.c b/userspace/libpman/src/lifecycle.c index 8056252832..125a6b3bb8 100644 --- a/userspace/libpman/src/lifecycle.c +++ b/userspace/libpman/src/lifecycle.c @@ -42,8 +42,7 @@ int pman_prepare_progs_before_loading() { bool should_disable = chosen_idx != -1; if(!should_disable) { if(progs[idx].feat > 0 && - libbpf_probe_bpf_helper(BPF_PROG_TYPE_RAW_TRACEPOINT, progs[idx].feat, NULL) == - 0) { + libbpf_probe_bpf_helper(BPF_PROG_TYPE_TRACING, progs[idx].feat, NULL) == 0) { snprintf(msg, MAX_ERROR_MESSAGE_LEN, "BPF program '%s' did not satisfy required feature [%d]",