From 227690e07a46fa6fe2f5093f2b995cb344955159 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Wed, 25 Jan 2023 00:28:11 +0100 Subject: [PATCH] new: support `io_uring_register` syscall Signed-off-by: Andrea Terzolo --- driver/bpf/fillers.h | 55 +++++------- .../definitions/events_dimensions.h | 2 + .../io_uring_register.bpf.c | 84 +++++++++++++++++++ driver/ppm_fillers.c | 32 ++++--- .../io_uring_register_e.cpp | 44 ++++++++++ .../io_uring_register_x.cpp | 59 +++++++++++++ userspace/libpman/src/events_prog_names.h | 2 + 7 files changed, 225 insertions(+), 53 deletions(-) create mode 100644 driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/io_uring_register.bpf.c create mode 100644 test/drivers/test_suites/syscall_enter_suite/io_uring_register_e.cpp create mode 100644 test/drivers/test_suites/syscall_exit_suite/io_uring_register_x.cpp diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 1cd36451cc5..5f10ab7d15d 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -3422,46 +3422,29 @@ FILLER(sys_io_uring_enter_x, true) FILLER(sys_io_uring_register_x, true) { - long retval; - int res; - unsigned long val; - - retval = bpf_syscall_get_retval(data->ctx); - res = bpf_val_to_ring(data, retval); - if (res != PPM_SUCCESS) - return res; - - /* - * fd - */ - val = bpf_syscall_get_argument(data, 0); - res = bpf_val_to_ring(data, val); - if (res != PPM_SUCCESS) - return res; + /* Parameter 1: res (type: PT_ERRNO) */ + long retval = bpf_syscall_get_retval(data->ctx); + int res = bpf_val_to_ring(data, retval); + CHECK_RES(res); - /* - * opcode - */ - val = bpf_syscall_get_argument(data, 1); - res = bpf_val_to_ring(data, io_uring_register_opcodes_to_scap(val)); - if (res != PPM_SUCCESS) - return res; + /* Parameter 2: fd (type: PT_FD) */ + s32 fd = (s32)bpf_syscall_get_argument(data, 0); + res = bpf_val_to_ring(data, (s64)fd); + CHECK_RES(res); - /* - * args - */ - val = bpf_syscall_get_argument(data, 2); - res = bpf_val_to_ring(data, val); - if (res != PPM_SUCCESS) - return res; + /* Parameter 3: opcode (type: PT_ENUMFLAGS16) */ + u32 opcode = (u32)bpf_syscall_get_argument(data, 1); + res = bpf_val_to_ring(data, io_uring_register_opcodes_to_scap(opcode)); + CHECK_RES(res); - /* - * nr_args - */ - val = bpf_syscall_get_argument(data, 3); - res = bpf_val_to_ring(data, val); + /* Parameter 4: arg (type: PT_UINT64) */ + unsigned long arg = bpf_syscall_get_argument(data, 2); + res = bpf_val_to_ring(data, arg); + CHECK_RES(res); - return res; + /* Parameter 5: nr_args (type: PT_UINT32) */ + u32 nr_args = (u32)bpf_syscall_get_argument(data, 3); + return bpf_val_to_ring(data, nr_args); } FILLER(sys_mlock_x, true) diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index 29ad7b11fab..704685f128d 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -154,6 +154,8 @@ #define MUNLOCKALL_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #define IO_URING_ENTER_E_SIZE HEADER_LEN #define IO_URING_ENTER_X_SIZE HEADER_LEN + sizeof(int64_t) * 2 + sizeof(uint32_t) * 4 + PARAM_LEN * 6 +#define IO_URING_REGISTER_E_SIZE HEADER_LEN +#define IO_URING_REGISTER_X_SIZE HEADER_LEN + sizeof(int64_t) * 2 + sizeof(uint16_t) + sizeof(uint64_t) + sizeof(uint32_t) + PARAM_LEN * 5 /* Generic tracepoints events. */ #define PROC_EXIT_SIZE HEADER_LEN + sizeof(int64_t) * 2 + sizeof(uint8_t) * 2 + PARAM_LEN * 4 diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/io_uring_register.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/io_uring_register.bpf.c new file mode 100644 index 00000000000..6357a57b3c1 --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/io_uring_register.bpf.c @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2023 The Falco Authors. + * + * This file is dual licensed under either the MIT or GPL 2. See MIT.txt + * or GPL2.txt for full copies of the license. + */ + +#include + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(io_uring_register_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, IO_URING_REGISTER_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_IO_URING_REGISTER_E); + + /*=============================== 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(io_uring_register_x, + struct pt_regs *regs, + long ret) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, IO_URING_REGISTER_X_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_IO_URING_REGISTER_X); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_ERRNO) */ + ringbuf__store_s64(&ringbuf, ret); + + /* Parameter 2: fd (type: PT_FD) */ + s32 fd = (s32)extract__syscall_argument(regs, 0); + ringbuf__store_s64(&ringbuf, (s64)fd); + + /* Parameter 3: opcode (type: PT_ENUMFLAGS16) */ + u32 opcode = (u32)extract__syscall_argument(regs, 1); + ringbuf__store_u16(&ringbuf, (u16)io_uring_register_opcodes_to_scap(opcode)); + + /* Parameter 4: arg (type: PT_UINT64) */ + /* Here we push directly a pointer to userspace. `arg` is + * pointer to `struct io_uring_rsrc_register` + */ + unsigned long arg = extract__syscall_argument(regs, 2); + ringbuf__store_u64(&ringbuf, arg); + + /* Parameter 5: nr_args (type: PT_UINT32) */ + u32 nr_args = (u32)extract__syscall_argument(regs, 3); + ringbuf__store_u32(&ringbuf, nr_args); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + ringbuf__submit_event(&ringbuf); + + return 0; +} + +/*=============================== EXIT EVENT ===========================*/ diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index 7aac57e7491..9f7e813343d 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -5220,37 +5220,35 @@ int f_sys_io_uring_enter_x(struct event_filler_arguments *args) int f_sys_io_uring_register_x (struct event_filler_arguments *args) { - int res; - unsigned long val; + int res = 0; + unsigned long val = 0; + s32 fd = 0; + /* Parameter 1: res (type: PT_ERRNO) */ int64_t retval = (int64_t)syscall_get_return_value(current, args->regs); res = val_to_ring(args, retval, 0, false, 0); - if (unlikely(res != PPM_SUCCESS)) - return res; + CHECK_RES(res); - /* fd */ + /* Parameter 2: fd (type: PT_FD) */ syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val); - res = val_to_ring(args, val, 0, true, 0); - if (unlikely(res != PPM_SUCCESS)) - return res; + fd = (s32)val; + res = val_to_ring(args, (s64)fd, 0, true, 0); + CHECK_RES(res); - /* opcode */ + /* Parameter 3: opcode (type: PT_UINT32) */ syscall_get_arguments_deprecated(current, args->regs, 1, 1, &val); res = val_to_ring(args, io_uring_register_opcodes_to_scap(val) , 0 , true, 0); - if (unlikely(res != PPM_SUCCESS)) - return res; + CHECK_RES(res); - /* arg */ + /* Parameter 4: arg (type: PT_UINT64) */ syscall_get_arguments_deprecated(current, args->regs, 2, 1, &val); res = val_to_ring(args, val, 0, true, 0); - if (unlikely(res != PPM_SUCCESS)) - return res; + CHECK_RES(res); - /* nr_args */ + /* Parameter 5: nr_args (type: PT_UINT32) */ syscall_get_arguments_deprecated(current, args->regs, 3, 1, &val); res = val_to_ring(args, val, 0, true, 0); - if (unlikely(res != PPM_SUCCESS)) - return res; + CHECK_RES(res); return add_sentinel(args); } diff --git a/test/drivers/test_suites/syscall_enter_suite/io_uring_register_e.cpp b/test/drivers/test_suites/syscall_enter_suite/io_uring_register_e.cpp new file mode 100644 index 00000000000..1a9f7aabce8 --- /dev/null +++ b/test/drivers/test_suites/syscall_enter_suite/io_uring_register_e.cpp @@ -0,0 +1,44 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_io_uring_register) + +#include + +TEST(SyscallEnter, io_uring_registerE) +{ + auto evt_test = get_syscall_event_test(__NR_io_uring_register, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + int32_t fd = -1; + uint32_t opcode = IORING_REGISTER_BUFFERS; + const void* arg = NULL; + unsigned int nr_args = 7; + assert_syscall_state(SYSCALL_FAILURE, "io_uring_register", syscall(__NR_io_uring_register, fd, opcode, arg, nr_args)); + + /*=============================== 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/drivers/test_suites/syscall_exit_suite/io_uring_register_x.cpp b/test/drivers/test_suites/syscall_exit_suite/io_uring_register_x.cpp new file mode 100644 index 00000000000..66bd6dffb19 --- /dev/null +++ b/test/drivers/test_suites/syscall_exit_suite/io_uring_register_x.cpp @@ -0,0 +1,59 @@ +#include "../../event_class/event_class.h" + +#if defined(__NR_io_uring_register) + +#include + +TEST(SyscallExit, io_uring_registerX) +{ + auto evt_test = get_syscall_event_test(__NR_io_uring_register, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + int32_t fd = -1; + uint32_t opcode = IORING_REGISTER_RESTRICTIONS; + const void* arg = (const void*)0x7fff5694dc58; + unsigned int nr_args = 34; + assert_syscall_state(SYSCALL_FAILURE, "io_uring_register", syscall(__NR_io_uring_register, fd, opcode, arg, nr_args)); + 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: fd (type: PT_FD) */ + evt_test->assert_numeric_param(2, (int64_t)fd); + + /* Parameter 3: opcode (type: PT_ENUMFLAGS16) */ + evt_test->assert_numeric_param(3, (uint16_t)opcode); + + /* Parameter 4: arg (type: PT_UINT64) */ + evt_test->assert_numeric_param(4, (uint64_t)arg); + + /* Parameter 5: nr_args (type: PT_UINT32) */ + evt_test->assert_numeric_param(5, (uint32_t)nr_args); + + + /*=============================== ASSERT PARAMETERS ===========================*/ + + evt_test->assert_num_params_pushed(5); +} +#endif diff --git a/userspace/libpman/src/events_prog_names.h b/userspace/libpman/src/events_prog_names.h index 39b1a56d5c6..295effc1bb2 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -209,6 +209,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [PPME_SYSCALL_MUNLOCKALL_X] = "munlockall_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", }; /* Some events can require more than one bpf program to collect all the data. */