From decbc3bd092c997882aad124e19f37f3e1a85278 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 29 Jul 2022 20:02:35 +0200 Subject: [PATCH] new(modern_bpf): add `fchmodat` syscall Signed-off-by: Andrea Terzolo --- .../definitions/events_dimensions.h | 1 + .../syscall_dispatched_events/fchmodat.bpf.c | 85 +++++++++++++++++++ .../syscall_enter_suite/fchmodat_e.cpp | 41 +++++++++ .../syscall_exit_suite/fchmodat_x.cpp | 52 ++++++++++++ userspace/libpman/src/events_prog_names.h | 2 + 5 files changed, 181 insertions(+) create mode 100644 driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fchmodat.bpf.c create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/fchmodat_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/fchmodat_x.cpp diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index e0419ee49b..e7f759c8f5 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -27,5 +27,6 @@ #define FCHDIR_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #define FCHMOD_E_SIZE HEADER_LEN #define FCHMOD_X_SIZE HEADER_LEN + sizeof(int64_t) * 2 + sizeof(uint32_t) + PARAM_LEN * 3 +#define FCHMODAT_E_SIZE HEADER_LEN #endif /* __EVENT_DIMENSIONS_H__ */ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fchmodat.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fchmodat.bpf.c new file mode 100644 index 0000000000..2551109e07 --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fchmodat.bpf.c @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2022 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. + */ + +#include +#include + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(fchmodat_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, FCHMODAT_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_FCHMODAT_E, FCHMODAT_E_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + // Here we have no parameters to collect. + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== ENTER EVENT ===========================*/ + +/*=============================== EXIT EVENT ===========================*/ + +SEC("tp_btf/sys_exit") +int BPF_PROG(fchmodat_x, + struct pt_regs *regs, + long ret) +{ + struct auxiliary_map *auxmap = auxmap__get(); + if(!auxmap) + { + return 0; + } + + auxmap__preload_event_header(auxmap, PPME_SYSCALL_FCHMODAT_X); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_ERRNO) */ + auxmap__store_s64_param(auxmap, ret); + + /* Parameter 2: dirfd (type: PT_FD) */ + s32 dirfd = (s32)extract__syscall_argument(regs, 0); + if(dirfd == AT_FDCWD) + { + dirfd = PPM_AT_FDCWD; + } + auxmap__store_s64_param(auxmap, (s64)dirfd); + + /* Parameter 3: filename (type: PT_FSRELPATH) */ + unsigned long path_pointer = extract__syscall_argument(regs, 1); + auxmap__store_charbuf_param(auxmap, path_pointer, USER); + + /* Parameter 4: mode (type: PT_MODE) */ + unsigned long mode = extract__syscall_argument(regs, 2); + auxmap__store_u32_param(auxmap, chmod_mode_to_scap(mode)); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + auxmap__finalize_event_header(auxmap); + + auxmap__submit_event(auxmap); + + return 0; +} + + +/*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/fchmodat_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/fchmodat_e.cpp new file mode 100644 index 0000000000..51de5f3887 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/fchmodat_e.cpp @@ -0,0 +1,41 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_fchmodat +TEST(SyscallEnter, fchmodatE) +{ + auto evt_test = new event_test(__NR_fchmodat, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + int32_t mock_dirfd = 0; + const char* pathname = NULL; + uint32_t mode = 0; + uint32_t flags = 0; + assert_syscall_state(SYSCALL_FAILURE, "fchmodat", syscall(__NR_fchmodat, mock_dirfd, pathname, mode, flags)); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + evt_test->disable_capture(); + + evt_test->assert_event_presence(); + + if(HasFatalFailure()) + { + return; + } + + evt_test->parse_event(); + + evt_test->assert_header(); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + // Here we have no parameters to assert. + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(0); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/fchmodat_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/fchmodat_x.cpp new file mode 100644 index 0000000000..808a7707c5 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/fchmodat_x.cpp @@ -0,0 +1,52 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_fchmodat +TEST(SyscallExit, fchmodatX) +{ + auto evt_test = new event_test(__NR_fchmodat, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + int32_t mock_dirfd = -1; + const char* pathname = "*//null"; + uint32_t mode = S_IXUSR; + uint32_t flags = 0; + assert_syscall_state(SYSCALL_FAILURE, "fchmodat", syscall(__NR_fchmodat, mock_dirfd, pathname, mode, flags)); + int64_t errno_value = -errno; + + /*=============================== TRIGGER SYSCALL ===========================*/ + + evt_test->disable_capture(); + + evt_test->assert_event_presence(); + + if(HasFatalFailure()) + { + return; + } + + evt_test->parse_event(); + + evt_test->assert_header(); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_ERRNO) */ + evt_test->assert_numeric_param(1, (int64_t)errno_value); + + /* Parameter 2: dirfd (type: PT_FD) */ + evt_test->assert_numeric_param(2, (int64_t)mock_dirfd); + + /* Parameter 3: filename (type: PT_FSPATH) */ + evt_test->assert_charbuf_param(3, pathname); + + /* Parameter 4: mode (type: PT_MODE) */ + evt_test->assert_numeric_param(4, (uint32_t)PPM_S_IXUSR); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(4); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 0f2012000b..8980089fe3 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -41,6 +41,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [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", }; /* Some events can require more than one bpf program to collect all the data. */