Skip to content

Commit

Permalink
new: support io_uring_register syscall
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Terzolo <[email protected]>
  • Loading branch information
Andreagit97 committed Jan 24, 2023
1 parent 24403b5 commit 227690e
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 53 deletions.
55 changes: 19 additions & 36 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions driver/modern_bpf/definitions/events_dimensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <helpers/interfaces/fixed_size_event.h>

/*=============================== 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 ===========================*/
32 changes: 15 additions & 17 deletions driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "../../event_class/event_class.h"

#if defined(__NR_io_uring_register)

#include <linux/io_uring.h>

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
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include "../../event_class/event_class.h"

#if defined(__NR_io_uring_register)

#include <linux/io_uring.h>

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
2 changes: 2 additions & 0 deletions userspace/libpman/src/events_prog_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down

0 comments on commit 227690e

Please sign in to comment.