From 14c54390e58c1681de8ac31274be772fe087cdb1 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 12:00:29 +0200 Subject: [PATCH 01/11] new(modern_bpf): add `eventfd` syscall Signed-off-by: Andrea Terzolo --- .../definitions/events_dimensions.h | 2 + .../syscall_dispatched_events/eventfd.bpf.c | 74 +++++++++++++++++++ .../syscall_enter_suite/eventfd_e.cpp | 46 ++++++++++++ .../syscall_exit_suite/eventfd_x.cpp | 42 +++++++++++ userspace/libpman/src/events_prog_names.h | 2 + 5 files changed, 166 insertions(+) create mode 100644 driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/eventfd.bpf.c create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index 6b9e17f15a..b065344688 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -40,5 +40,7 @@ #define FCHMODAT_E_SIZE HEADER_LEN #define MKDIRAT_E_SIZE HEADER_LEN #define RMDIR_E_SIZE HEADER_LEN +#define EVENTFD_E_SIZE HEADER_LEN + sizeof(uint64_t) + sizeof(uint32_t) + PARAM_LEN * 2 +#define EVENTFD_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #endif /* __EVENT_DIMENSIONS_H__ */ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/eventfd.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/eventfd.bpf.c new file mode 100644 index 0000000000..76fdbc1b50 --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/eventfd.bpf.c @@ -0,0 +1,74 @@ +/* + * 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 + +/* These BPF programs are used for `eventfd` and `eventfd2` syscalls. */ + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(eventfd_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, EVENTFD_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_EVENTFD_E, EVENTFD_E_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: initval (type: PT_UINT64) */ + u32 initval = (u32)extract__syscall_argument(regs, 0); + ringbuf__store_u64(&ringbuf, (u64)initval); + + /* Parameter 2: flags (type: PT_FLAGS32) */ + /// TODO: Right now we don't catch any flag. + u32 flags = 0; + ringbuf__store_u32(&ringbuf, flags); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== ENTER EVENT ===========================*/ + +/*=============================== EXIT EVENT ===========================*/ + +SEC("tp_btf/sys_exit") +int BPF_PROG(eventfd_x, + struct pt_regs *regs, + long ret) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, EVENTFD_X_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_EVENTFD_X, EVENTFD_X_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_FD)*/ + ringbuf__store_s64(&ringbuf, ret); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp new file mode 100644 index 0000000000..de558e7b91 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp @@ -0,0 +1,46 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_eventfd) && defined(__NR_close) +TEST(SyscallEnter, eventfdE) +{ + auto evt_test = new event_test(__NR_eventfd, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + uint32_t initval = 3; + int flags = 0; + int32_t fd = syscall(__NR_eventfd, initval, flags); + assert_syscall_state(SYSCALL_SUCCESS, "eventfd", fd, NOT_EQUAL, -1); + syscall(__NR_close, fd); + + /*=============================== 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: initval (type: PT_UINT64) */ + evt_test->assert_numeric_param(1, (uint64_t)initval); + + /* Parameter 2: flags (type: PT_FLAGS32) */ + /* Right now we don't catch any flag, so we expect `0` as a second parameter. */ + evt_test->assert_numeric_param(2, (uint32_t)0); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(2); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp new file mode 100644 index 0000000000..9e65d11363 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp @@ -0,0 +1,42 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_eventfd) && defined(__NR_close) +TEST(SyscallExit, eventfdX) +{ + auto evt_test = new event_test(__NR_eventfd, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + uint32_t initval = 3; + int flags = 0; + int32_t fd = syscall(__NR_eventfd, initval, flags); + assert_syscall_state(SYSCALL_SUCCESS, "eventfd", fd, NOT_EQUAL, -1); + syscall(__NR_close, fd); + + /*=============================== 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_FD) */ + evt_test->assert_numeric_param(1, (int64_t)fd); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 634bde700b..4644316a27 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -59,6 +59,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [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", }; /* Some events can require more than one bpf program to collect all the data. */ From 81f6a0fca6a30aa29f586757b845574f7e46f3b4 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 12:11:05 +0200 Subject: [PATCH 02/11] new(modern_bpf): add `eventfd2` syscall Signed-off-by: Andrea Terzolo --- .../syscall_enter_suite/eventfd2_e.cpp | 52 +++++++++++++++++++ .../syscall_exit_suite/eventfd2_x.cpp | 48 +++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/eventfd2_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/eventfd2_x.cpp diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/eventfd2_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/eventfd2_e.cpp new file mode 100644 index 0000000000..e25bb21b85 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/eventfd2_e.cpp @@ -0,0 +1,52 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_eventfd2) && defined(__NR_close) +TEST(SyscallEnter, eventfd2E) +{ + + /* Please note: + * the syscall `eventfd2` is mapped to `PPME_SYSCALL_EVENTFD_E` event + * like `eventfd`. The same BPF program will be used for both the syscalls. + */ + + auto evt_test = new event_test(__NR_eventfd2, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + uint32_t initval = 3; + int flags = 0; + int32_t fd = syscall(__NR_eventfd2, initval, flags); + assert_syscall_state(SYSCALL_SUCCESS, "eventfd2", fd, NOT_EQUAL, -1); + syscall(__NR_close, fd); + + /*=============================== 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: initval (type: PT_UINT64) */ + evt_test->assert_numeric_param(1, (uint64_t)initval); + + /* Parameter 2: flags (type: PT_FLAGS32) */ + /* Right now we don't catch any flag, so we expect `0` as a second parameter. */ + evt_test->assert_numeric_param(2, (uint32_t)0); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(2); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/eventfd2_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/eventfd2_x.cpp new file mode 100644 index 0000000000..80534accdc --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/eventfd2_x.cpp @@ -0,0 +1,48 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_eventfd2) && defined(__NR_close) +TEST(SyscallExit, eventfd2X) +{ + + /* Please note: + * the syscall `eventfd2` is mapped to `PPME_SYSCALL_EVENTFD_X` event + * like `eventfd`. The same BPF program will be used for both the syscalls. + */ + + auto evt_test = new event_test(__NR_eventfd2, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + uint32_t initval = 3; + int flags = 0; + int32_t fd = syscall(__NR_eventfd2, initval, flags); + assert_syscall_state(SYSCALL_SUCCESS, "eventfd2", fd, NOT_EQUAL, -1); + syscall(__NR_close, fd); + + /*=============================== 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_FD) */ + evt_test->assert_numeric_param(1, (int64_t)fd); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif From 04ed4bc45b469dac2f1ecf63042f416dcf8e8ac6 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 12:37:21 +0200 Subject: [PATCH 03/11] new(modern_bpf): add `inotify_init` syscall Signed-off-by: Andrea Terzolo --- .../definitions/events_dimensions.h | 2 + .../inotify_init.bpf.c | 72 +++++++++++++++++++ .../syscall_enter_suite/inotify_init_e.cpp | 42 +++++++++++ .../syscall_exit_suite/inotify_init_x.cpp | 42 +++++++++++ userspace/libpman/src/events_prog_names.h | 2 + 5 files changed, 160 insertions(+) create mode 100644 driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index b065344688..5b1296639d 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -42,5 +42,7 @@ #define RMDIR_E_SIZE HEADER_LEN #define EVENTFD_E_SIZE HEADER_LEN + sizeof(uint64_t) + sizeof(uint32_t) + PARAM_LEN * 2 #define EVENTFD_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN +#define INOTIFY_INIT_E_SIZE HEADER_LEN + sizeof(uint8_t) + PARAM_LEN +#define INOTIFY_INIT_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #endif /* __EVENT_DIMENSIONS_H__ */ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c new file mode 100644 index 0000000000..ec4c7ca585 --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c @@ -0,0 +1,72 @@ +/* + * 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 + +/* These BPF programs are used for `inotify_init` and `inotify_init1` syscalls. */ + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(inotify_init_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, INOTIFY_INIT_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_INOTIFY_INIT_E, INOTIFY_INIT_E_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: flags (type: PT_FLAGS8) */ + /// TODO: please note `int inotify_init(void)` has not a first parameter only + /// `inotify_init1` as a flag parameter... we could generate 2 new events to + /// manage this situation. + u8 flags = (u8)extract__syscall_argument(regs, 0); + ringbuf__store_u8(&ringbuf, flags); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== ENTER EVENT ===========================*/ + +/*=============================== EXIT EVENT ===========================*/ + +SEC("tp_btf/sys_exit") +int BPF_PROG(inotify_init_x, + struct pt_regs *regs, + long ret) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, INOTIFY_INIT_X_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_INOTIFY_INIT_X, INOTIFY_INIT_X_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_FD) */ + ringbuf__store_s64(&ringbuf, ret); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp new file mode 100644 index 0000000000..1e34592e1f --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp @@ -0,0 +1,42 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_inotify_init) && defined(__NR_close) +TEST(SyscallEnter, inotify_initE) +{ + + auto evt_test = new event_test(__NR_inotify_init, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + uint32_t flags = 15; + int32_t fd = syscall(__NR_inotify_init, flags); + assert_syscall_state(SYSCALL_SUCCESS, "inotify_init", fd, NOT_EQUAL, -1); + syscall(__NR_close, fd); + + /*=============================== 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: flags (type: PT_FLAGS8) */ + evt_test->assert_numeric_param(1, (uint8_t)flags); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp new file mode 100644 index 0000000000..41267dcd81 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp @@ -0,0 +1,42 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_inotify_init) && defined(__NR_close) +TEST(SyscallExit, inotify_initX) +{ + + auto evt_test = new event_test(__NR_inotify_init, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + uint32_t flags = 15; + int32_t fd = syscall(__NR_inotify_init, flags); + assert_syscall_state(SYSCALL_SUCCESS, "inotify_init", fd, NOT_EQUAL, -1); + syscall(__NR_close, fd); + + /*=============================== 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: fd (type: PT_FD) */ + evt_test->assert_numeric_param(1, (int64_t)fd); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 4644316a27..dc1bc74a87 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -61,6 +61,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [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", }; /* Some events can require more than one bpf program to collect all the data. */ From aec35ccd63d9fe70e0b4c92cdbcf0a14b3f43840 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 12:46:48 +0200 Subject: [PATCH 04/11] new(modern_bpf): add `inotify_init1` syscall Signed-off-by: Andrea Terzolo --- .../syscall_enter_suite/inotify_init1_e.cpp | 46 ++++++++++++++++++ .../syscall_exit_suite/inotify_init1_x.cpp | 47 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/inotify_init1_x.cpp diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp new file mode 100644 index 0000000000..3e98edc845 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp @@ -0,0 +1,46 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_inotify_init1) +TEST(SyscallEnter, inotify_init1E) +{ + + /* Please note: + * the syscall `inotify_init1` is mapped to `PPME_SYSCALL_INOTIFY_INIT_E` event + * like `inotify_init`. The same BPF program will be used for both the syscalls. + */ + + auto evt_test = new event_test(__NR_inotify_init1, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `flags = 15` is an invalid value so the syscall will return `EINVAL` as errno. */ + uint32_t flags = 15; + assert_syscall_state(SYSCALL_FAILURE, "inotify_init1", syscall(__NR_inotify_init1, 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 ===========================*/ + + /* Parameter 1: flags (type: PT_FLAGS8) */ + evt_test->assert_numeric_param(1, (uint8_t)flags); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init1_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init1_x.cpp new file mode 100644 index 0000000000..d8ec56af63 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init1_x.cpp @@ -0,0 +1,47 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_inotify_init1) +TEST(SyscallExit, inotify_init1X) +{ + + /* Please note: + * the syscall `inotify_init1` is mapped to `PPME_SYSCALL_INOTIFY_INIT_X` event + * like `inotify_init`. The same BPF program will be used for both the syscalls. + */ + + auto evt_test = new event_test(__NR_inotify_init1, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `flags = 15` is an invalid value so the syscall will return `EINVAL` as errno. */ + uint32_t flags = 15; + assert_syscall_state(SYSCALL_FAILURE, "inotify_init1", syscall(__NR_inotify_init1, 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: fd (type: PT_FD) */ + evt_test->assert_numeric_param(1, errno_value); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif From 2751f6d69335436ac1b974da4c7dd360ccf89ccc Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 13:09:26 +0200 Subject: [PATCH 05/11] new(modern_bpf): add `timerfd_create` syscall Signed-off-by: Andrea Terzolo --- .../definitions/events_dimensions.h | 2 + .../timerfd_create.bpf.c | 71 +++++++++++++++++++ .../syscall_enter_suite/timerfd_create_e.cpp | 44 ++++++++++++ .../syscall_exit_suite/timerfd_create_x.cpp | 42 +++++++++++ userspace/libpman/src/events_prog_names.h | 2 + 5 files changed, 161 insertions(+) create mode 100644 driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/timerfd_create.bpf.c create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/timerfd_create_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/timerfd_create_x.cpp diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index 5b1296639d..0ed6c6dd70 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -44,5 +44,7 @@ #define EVENTFD_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #define INOTIFY_INIT_E_SIZE HEADER_LEN + sizeof(uint8_t) + PARAM_LEN #define INOTIFY_INIT_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN +#define TIMERFD_CREATE_E_SIZE HEADER_LEN + sizeof(uint8_t) * 2 + PARAM_LEN * 2 +#define TIMERFD_CREATE_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #endif /* __EVENT_DIMENSIONS_H__ */ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/timerfd_create.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/timerfd_create.bpf.c new file mode 100644 index 0000000000..e884e9153e --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/timerfd_create.bpf.c @@ -0,0 +1,71 @@ +/* + * 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 + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(timerfd_create_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, TIMERFD_CREATE_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_TIMERFD_CREATE_E, TIMERFD_CREATE_E_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: clockid (type: PT_UINT8) */ + /* Like in the old probe we send `0` */ + ringbuf__store_u8(&ringbuf, 0); + + /* Parameter 2: flags (type: PT_FLAGS8) */ + /* Like in the old probe we send `0` */ + ringbuf__store_u8(&ringbuf, 0); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== ENTER EVENT ===========================*/ + +/*=============================== EXIT EVENT ===========================*/ + +SEC("tp_btf/sys_exit") +int BPF_PROG(timerfd_create_x, + struct pt_regs *regs, + long ret) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, TIMERFD_CREATE_X_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_TIMERFD_CREATE_X, TIMERFD_CREATE_X_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_FD)*/ + ringbuf__store_s64(&ringbuf, ret); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/timerfd_create_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/timerfd_create_e.cpp new file mode 100644 index 0000000000..5835315381 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/timerfd_create_e.cpp @@ -0,0 +1,44 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_timerfd_create +TEST(SyscallEnter, timerfd_createE) +{ + auto evt_test = new event_test(__NR_timerfd_create, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `clockid` and `flags` are not caught BPF side, we always send `0` */ + int clockid = -1; + int flags = -1; + assert_syscall_state(SYSCALL_FAILURE,"timerfd_create", syscall(__NR_timerfd_create, clockid, 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 ===========================*/ + + /* Parameter 1: clockid (type: PT_UINT8) */ + evt_test->assert_numeric_param(1, (uint8_t)0); + + /* Parameter 2: flags (type: PT_FLAGS8) */ + evt_test->assert_numeric_param(2, (uint8_t)0); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(2); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/timerfd_create_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/timerfd_create_x.cpp new file mode 100644 index 0000000000..d44e6b3606 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/timerfd_create_x.cpp @@ -0,0 +1,42 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_timerfd_create +TEST(SyscallExit, timerfd_createX) +{ + auto evt_test = new event_test(__NR_timerfd_create, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `clockid` and `flags` are not caught BPF side, we always send `0` */ + int clockid = -1; + int flags = -1; + assert_syscall_state(SYSCALL_FAILURE,"timerfd_create", syscall(__NR_timerfd_create, clockid, 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_FD) */ + evt_test->assert_numeric_param(1, (int64_t)errno_value); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index dc1bc74a87..6e1d65666a 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -63,6 +63,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [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", }; /* Some events can require more than one bpf program to collect all the data. */ From 7ee10854f3ed51cf3535d723d86ccd54d3be9b9b Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 14:50:22 +0200 Subject: [PATCH 06/11] new(modern_bpf): add `userfaultfd` syscall Signed-off-by: Andrea Terzolo --- .../definitions/events_dimensions.h | 2 + .../userfaultfd.bpf.c | 69 +++++++++++++++++++ .../syscall_enter_suite/userfaultfd_e.cpp | 39 +++++++++++ .../syscall_exit_suite/userfaultfd_x.cpp | 44 ++++++++++++ userspace/libpman/src/events_prog_names.h | 2 + 5 files changed, 156 insertions(+) create mode 100644 driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/userfaultfd.bpf.c create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/userfaultfd_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/userfaultfd_x.cpp diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index 0ed6c6dd70..1748ea874c 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -46,5 +46,7 @@ #define INOTIFY_INIT_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #define TIMERFD_CREATE_E_SIZE HEADER_LEN + sizeof(uint8_t) * 2 + PARAM_LEN * 2 #define TIMERFD_CREATE_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN +#define USERFAULTFD_E_SIZE HEADER_LEN +#define USERFAULTFD_X_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + PARAM_LEN * 2 #endif /* __EVENT_DIMENSIONS_H__ */ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/userfaultfd.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/userfaultfd.bpf.c new file mode 100644 index 0000000000..b19df231cb --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/userfaultfd.bpf.c @@ -0,0 +1,69 @@ +/* + * 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 + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(userfaultfd_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, USERFAULTFD_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_USERFAULTFD_E, USERFAULTFD_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(userfaultfd_x, + struct pt_regs *regs, + long ret) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, USERFAULTFD_X_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_USERFAULTFD_X, USERFAULTFD_X_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_ERRNO) */ + ringbuf__store_s64(&ringbuf, ret); + + /* Parameter 2: flags (type: PT_FLAGS32) */ + u32 flags = (u32)extract__syscall_argument(regs, 0); + ringbuf__store_u32(&ringbuf, flags); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/userfaultfd_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/userfaultfd_e.cpp new file mode 100644 index 0000000000..82bd0f8eab --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/userfaultfd_e.cpp @@ -0,0 +1,39 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_userfaultfd +TEST(SyscallEnter, userfaultfdE) +{ + auto evt_test = new event_test(__NR_userfaultfd, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `flags = 3` is an invalid flag value so the syscall will return `EINVAL` as errno. */ + int flags = 3; + assert_syscall_state(SYSCALL_FAILURE, "userfaultfd", syscall(__NR_userfaultfd, 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/userfaultfd_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/userfaultfd_x.cpp new file mode 100644 index 0000000000..ec0426fb6e --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/userfaultfd_x.cpp @@ -0,0 +1,44 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_userfaultfd +TEST(SyscallExit, userfaultfdX) +{ + auto evt_test = new event_test(__NR_userfaultfd, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `flags = 3` is an invalid flag value so the syscall will return `EINVAL` as errno. */ + int flags = 3; + assert_syscall_state(SYSCALL_FAILURE, "userfaultfd", syscall(__NR_userfaultfd, 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_FD) */ + evt_test->assert_numeric_param(1, (int64_t)errno_value); + + /* Parameter 2: flags (type: PT_FLAGS32) */ + evt_test->assert_numeric_param(2, (uint32_t)flags); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(2); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 6e1d65666a..7cf9b10c81 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -65,6 +65,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [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", }; /* Some events can require more than one bpf program to collect all the data. */ From 7767b3ee8bb0ad0b42778aeae83b203ea243896d Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 16:06:09 +0200 Subject: [PATCH 07/11] new(modern_bpf): add `signalfd` syscall Signed-off-by: Andrea Terzolo --- .../definitions/events_dimensions.h | 2 + .../syscall_dispatched_events/signalfd.bpf.c | 78 +++++++++++++++++++ .../syscall_enter_suite/signalfd_e.cpp | 53 +++++++++++++ .../syscall_exit_suite/signalfd_x.cpp | 46 +++++++++++ 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/signalfd.bpf.c create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index 1748ea874c..7c3f6ba5db 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -48,5 +48,7 @@ #define TIMERFD_CREATE_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #define USERFAULTFD_E_SIZE HEADER_LEN #define USERFAULTFD_X_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + PARAM_LEN * 2 +#define SIGNALFD_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + sizeof(uint8_t) + PARAM_LEN * 3 +#define SIGNALFD_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #endif /* __EVENT_DIMENSIONS_H__ */ diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c new file mode 100644 index 0000000000..6d99cbb0c2 --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c @@ -0,0 +1,78 @@ +/* + * 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 + +/* These BPF programs are used for `signalfd` and `signalfd4` syscalls. */ + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(signalfd_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, SIGNALFD_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_SIGNALFD_E, SIGNALFD_E_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: fd (type: PT_FD) */ + s32 fd = (s32)extract__syscall_argument(regs, 0); + ringbuf__store_s64(&ringbuf, (s64)fd); + + /* Parameter 2: mask (type: PT_UINT32) */ + /* Like in the old probe we send `0`. */ + ringbuf__store_u32(&ringbuf, 0); + + /* Parameter 3: flags (type: PT_FLAGS8) */ + /* Like in the old probe we send `0`. */ + ringbuf__store_u8(&ringbuf, 0); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== ENTER EVENT ===========================*/ + +/*=============================== EXIT EVENT ===========================*/ + +SEC("tp_btf/sys_exit") +int BPF_PROG(signalfd_x, + struct pt_regs *regs, + long ret) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, SIGNALFD_X_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_SIGNALFD_X, SIGNALFD_X_SIZE); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_FD)*/ + ringbuf__store_s64(&ringbuf, ret); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + + +/*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp new file mode 100644 index 0000000000..1b49a98309 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp @@ -0,0 +1,53 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_signalfd + +#include + +TEST(SyscallEnter, signalfdE) +{ + auto evt_test = new event_test(__NR_signalfd, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `mask` and `flags` are not caught BPF side. */ + int32_t mock_fd = -1; + sigset_t mask = {0}; + int flags = 7; + assert_syscall_state(SYSCALL_FAILURE, "signalfd", syscall(__NR_signalfd, mock_fd, &mask, 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 ===========================*/ + + /* Parameter 1: fd (type: PT_FD) */ + evt_test->assert_numeric_param(1, (int64_t)mock_fd); + + /* Parameter 2: mask (type: PT_UINT32) */ + /* Right now we don't catch any mask, so we expect `0` as a second parameter. */ + evt_test->assert_numeric_param(2, (uint32_t)0); + + /* Parameter 3: flags (type: PT_FLAGS8) */ + /* Right now we don't catch any flag, so we expect `0` as a second parameter. */ + evt_test->assert_numeric_param(3, (uint8_t)0); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(3); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp new file mode 100644 index 0000000000..9ee6ea863b --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp @@ -0,0 +1,46 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_signalfd + +#include + +TEST(SyscallExit, signalfdX) +{ + auto evt_test = new event_test(__NR_signalfd, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `mask` and `flags` are not caught BPF side. */ + int32_t mock_fd = -1; + sigset_t mask = {0}; + int flags = 7; + assert_syscall_state(SYSCALL_FAILURE, "signalfd", syscall(__NR_signalfd, mock_fd, &mask, 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); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 7cf9b10c81..ccf8061725 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -67,6 +67,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [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", }; /* Some events can require more than one bpf program to collect all the data. */ From 33a94ad2ee6f4db9ac629460f9a9eb94e3a0fadb Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 30 Jul 2022 16:14:46 +0200 Subject: [PATCH 08/11] new(modern_bpf): add `signalfd4` syscall Signed-off-by: Andrea Terzolo --- .../syscall_enter_suite/signalfd4_e.cpp | 59 +++++++++++++++++++ .../syscall_exit_suite/signalfd4_x.cpp | 52 ++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp create mode 100644 test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp new file mode 100644 index 0000000000..fe9f646752 --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp @@ -0,0 +1,59 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_signalfd4 + +#include + +TEST(SyscallEnter, signalfd4E) +{ + + /* Please note: + * the syscall `signalfd4` is mapped to `PPME_SYSCALL_SIGNALFD_E` event + * like `signalfd`. The same BPF program will be used for both the syscalls. + */ + + auto evt_test = new event_test(__NR_signalfd4, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `mask` and `flags` are not catched BPF side. */ + int32_t mock_fd = -1; + sigset_t mask = {0}; + int flags = 7; + assert_syscall_state(SYSCALL_FAILURE, "signalfd4", syscall(__NR_signalfd4, mock_fd, &mask, 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 ===========================*/ + + /* Parameter 1: fd (type: PT_FD) */ + evt_test->assert_numeric_param(1, (int64_t)mock_fd); + + /* Parameter 2: mask (type: PT_UINT32) */ + /* Right now we don't catch any mask, so we expect `0` as a second parameter. */ + evt_test->assert_numeric_param(2, (uint32_t)0); + + /* Parameter 3: flags (type: PT_FLAGS8) */ + /* Right now we don't catch any flag, so we expect `0` as a second parameter. */ + evt_test->assert_numeric_param(3, (uint8_t)0); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(3); +} +#endif diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp new file mode 100644 index 0000000000..ff4b0ead4c --- /dev/null +++ b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp @@ -0,0 +1,52 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_signalfd4 + +#include + +TEST(SyscallExit, signalfd4X) +{ + + /* Please note: + * the syscall `signalfd4` is mapped to `PPME_SYSCALL_SIGNALFD_X` event + * like `signalfd`. The same BPF program will be used for both the syscalls. + */ + + auto evt_test = new event_test(__NR_signalfd4, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + /* `mask` and `flags` are not catched BPF side. */ + int32_t mock_fd = -1; + sigset_t mask = {0}; + int flags = 7; + assert_syscall_state(SYSCALL_FAILURE, "signalfd4", syscall(__NR_signalfd4, mock_fd, &mask, 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); + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(1); +} +#endif From ad4a3d9a42b09b1f6e0ce5425b12ba5ca16cae2a Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Tue, 2 Aug 2022 19:31:10 +0200 Subject: [PATCH 09/11] test(modern_bpf): remove useless `flags` params Signed-off-by: Andrea Terzolo Co-authored-by: Hendrik Brueckner --- test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp | 3 +-- test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp index de558e7b91..b0d5aedae0 100644 --- a/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp +++ b/test/modern_bpf/test_suites/syscall_enter_suite/eventfd_e.cpp @@ -10,8 +10,7 @@ TEST(SyscallEnter, eventfdE) /*=============================== TRIGGER SYSCALL ===========================*/ uint32_t initval = 3; - int flags = 0; - int32_t fd = syscall(__NR_eventfd, initval, flags); + int32_t fd = syscall(__NR_eventfd, initval); assert_syscall_state(SYSCALL_SUCCESS, "eventfd", fd, NOT_EQUAL, -1); syscall(__NR_close, fd); diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp index 9e65d11363..b666b7efcd 100644 --- a/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp +++ b/test/modern_bpf/test_suites/syscall_exit_suite/eventfd_x.cpp @@ -10,8 +10,7 @@ TEST(SyscallExit, eventfdX) /*=============================== TRIGGER SYSCALL ===========================*/ uint32_t initval = 3; - int flags = 0; - int32_t fd = syscall(__NR_eventfd, initval, flags); + int32_t fd = syscall(__NR_eventfd, initval); assert_syscall_state(SYSCALL_SUCCESS, "eventfd", fd, NOT_EQUAL, -1); syscall(__NR_close, fd); From a3f74dfb7b7a8291a31c44b9d3132febdaee5235 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Tue, 2 Aug 2022 23:46:03 +0200 Subject: [PATCH 10/11] update(modern_bpf): avoid information leakage in `inotify_init` Signed-off-by: Andrea Terzolo Co-authored-by: Hendrik Brueckner --- .../events/syscall_dispatched_events/inotify_init.bpf.c | 7 ++++--- .../test_suites/syscall_enter_suite/inotify_init1_e.cpp | 4 +++- .../test_suites/syscall_enter_suite/inotify_init_e.cpp | 7 ++++--- .../test_suites/syscall_exit_suite/inotify_init_x.cpp | 3 +-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c index ec4c7ca585..5d358347a6 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/inotify_init.bpf.c @@ -28,9 +28,10 @@ int BPF_PROG(inotify_init_e, /* Parameter 1: flags (type: PT_FLAGS8) */ /// TODO: please note `int inotify_init(void)` has not a first parameter only - /// `inotify_init1` as a flag parameter... we could generate 2 new events to - /// manage this situation. - u8 flags = (u8)extract__syscall_argument(regs, 0); + /// `inotify_init1` as a flag parameter...To avoid information leakage taking + /// the value of first register even when we are not allowed, we default this + /// parameter to `0`... we could generate 2 new events to manage this situation. + u8 flags = 0; ringbuf__store_u8(&ringbuf, flags); /*=============================== COLLECT PARAMETERS ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp index 3e98edc845..e13d22b071 100644 --- a/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp +++ b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init1_e.cpp @@ -37,7 +37,9 @@ TEST(SyscallEnter, inotify_init1E) /*=============================== ASSERT PARAMETERS ===========================*/ /* Parameter 1: flags (type: PT_FLAGS8) */ - evt_test->assert_numeric_param(1, (uint8_t)flags); + /// TODO: Right now we send `0` to avoid problems with `inotify_init` since they + /// share the same event. We need to split them. + evt_test->assert_numeric_param(1, (uint8_t)0); /*=============================== ASSERT PARAMETERS ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp index 1e34592e1f..6e00a5ead0 100644 --- a/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp +++ b/test/modern_bpf/test_suites/syscall_enter_suite/inotify_init_e.cpp @@ -10,8 +10,7 @@ TEST(SyscallEnter, inotify_initE) /*=============================== TRIGGER SYSCALL ===========================*/ - uint32_t flags = 15; - int32_t fd = syscall(__NR_inotify_init, flags); + int32_t fd = syscall(__NR_inotify_init); assert_syscall_state(SYSCALL_SUCCESS, "inotify_init", fd, NOT_EQUAL, -1); syscall(__NR_close, fd); @@ -33,7 +32,9 @@ TEST(SyscallEnter, inotify_initE) /*=============================== ASSERT PARAMETERS ===========================*/ /* Parameter 1: flags (type: PT_FLAGS8) */ - evt_test->assert_numeric_param(1, (uint8_t)flags); + /// TODO: Right now we send `0` to avoid problems with `inotify_init` since they + /// share the same event. We need to split them. + evt_test->assert_numeric_param(1, (uint8_t)0); /*=============================== ASSERT PARAMETERS ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp index 41267dcd81..092264ec53 100644 --- a/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp +++ b/test/modern_bpf/test_suites/syscall_exit_suite/inotify_init_x.cpp @@ -10,8 +10,7 @@ TEST(SyscallExit, inotify_initX) /*=============================== TRIGGER SYSCALL ===========================*/ - uint32_t flags = 15; - int32_t fd = syscall(__NR_inotify_init, flags); + int32_t fd = syscall(__NR_inotify_init); assert_syscall_state(SYSCALL_SUCCESS, "inotify_init", fd, NOT_EQUAL, -1); syscall(__NR_close, fd); From 59aad71ab12c9e99e7768c8a556f655c7c1c65cd Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Wed, 3 Aug 2022 00:03:57 +0200 Subject: [PATCH 11/11] update(modern_bpf): add a missing parameter in `signalfd` syscalls Signed-off-by: Andrea Terzolo Co-authored-by: Hendrik Brueckner --- .../events/syscall_dispatched_events/signalfd.bpf.c | 5 ++++- .../test_suites/syscall_enter_suite/signalfd4_e.cpp | 3 ++- .../test_suites/syscall_enter_suite/signalfd_e.cpp | 6 +++--- .../test_suites/syscall_exit_suite/signalfd4_x.cpp | 3 ++- .../test_suites/syscall_exit_suite/signalfd_x.cpp | 6 +++--- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c index 6d99cbb0c2..00828cc175 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/signalfd.bpf.c @@ -35,6 +35,10 @@ int BPF_PROG(signalfd_e, ringbuf__store_u32(&ringbuf, 0); /* Parameter 3: flags (type: PT_FLAGS8) */ + /// TODO: this are not flags, but it is a sizemask, + /// please see here for more deatails: + /// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/signalfd.c#n302 + /// We need to create 2 separate events for `signalfd` and `signalfd4`. /* Like in the old probe we send `0`. */ ringbuf__store_u8(&ringbuf, 0); @@ -74,5 +78,4 @@ int BPF_PROG(signalfd_x, return 0; } - /*=============================== EXIT EVENT ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp index fe9f646752..8d66d9c2d0 100644 --- a/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp +++ b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd4_e.cpp @@ -21,8 +21,9 @@ TEST(SyscallEnter, signalfd4E) /* `mask` and `flags` are not catched BPF side. */ int32_t mock_fd = -1; sigset_t mask = {0}; + size_t sizemask = 0; int flags = 7; - assert_syscall_state(SYSCALL_FAILURE, "signalfd4", syscall(__NR_signalfd4, mock_fd, &mask, flags)); + assert_syscall_state(SYSCALL_FAILURE, "signalfd4", syscall(__NR_signalfd4, mock_fd, &mask, sizemask, flags)); /*=============================== TRIGGER SYSCALL ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp index 1b49a98309..ad95c687b8 100644 --- a/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp +++ b/test/modern_bpf/test_suites/syscall_enter_suite/signalfd_e.cpp @@ -12,11 +12,11 @@ TEST(SyscallEnter, signalfdE) /*=============================== TRIGGER SYSCALL ===========================*/ - /* `mask` and `flags` are not caught BPF side. */ + /* `mask` is not caught BPF side. */ int32_t mock_fd = -1; sigset_t mask = {0}; - int flags = 7; - assert_syscall_state(SYSCALL_FAILURE, "signalfd", syscall(__NR_signalfd, mock_fd, &mask, flags)); + size_t sizemask = 0; + assert_syscall_state(SYSCALL_FAILURE, "signalfd", syscall(__NR_signalfd, mock_fd, &mask, sizemask)); /*=============================== TRIGGER SYSCALL ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp index ff4b0ead4c..e876f3b02b 100644 --- a/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp +++ b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd4_x.cpp @@ -21,8 +21,9 @@ TEST(SyscallExit, signalfd4X) /* `mask` and `flags` are not catched BPF side. */ int32_t mock_fd = -1; sigset_t mask = {0}; + size_t sizemask = 0; int flags = 7; - assert_syscall_state(SYSCALL_FAILURE, "signalfd4", syscall(__NR_signalfd4, mock_fd, &mask, flags)); + assert_syscall_state(SYSCALL_FAILURE, "signalfd4", syscall(__NR_signalfd4, mock_fd, &mask, sizemask, flags)); int64_t errno_value = -errno; /*=============================== TRIGGER SYSCALL ===========================*/ diff --git a/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp index 9ee6ea863b..1261afe361 100644 --- a/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp +++ b/test/modern_bpf/test_suites/syscall_exit_suite/signalfd_x.cpp @@ -12,11 +12,11 @@ TEST(SyscallExit, signalfdX) /*=============================== TRIGGER SYSCALL ===========================*/ - /* `mask` and `flags` are not caught BPF side. */ + /* `mask` is not caught BPF side. */ int32_t mock_fd = -1; sigset_t mask = {0}; - int flags = 7; - assert_syscall_state(SYSCALL_FAILURE, "signalfd", syscall(__NR_signalfd, mock_fd, &mask, flags)); + size_t sizemask = 0; + assert_syscall_state(SYSCALL_FAILURE, "signalfd", syscall(__NR_signalfd, mock_fd, &mask, sizemask)); int64_t errno_value = -errno; /*=============================== TRIGGER SYSCALL ===========================*/