From 6e587f3a7fbee3ae3092be76eb14ed00ae199fe9 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Mon, 21 Aug 2023 16:53:56 -0700 Subject: [PATCH] Add fcntl enter arguments to exit event For some filters on fcntl events, it's useful to have access to both the provided fd and cmd, which are parameters in the enter event, as well as the return value (e.g. the new fd, which is in the exit event). So add the enter event fields to the exit event. This matches the pattern we already use for lots of other events. Fcntl is a pretty old event, so we weren't following that pattern then. It's safe to add new fields to events to preserve backwards compatibility, but it's not safe to modify or reduce fields, so keep the parameters in the enter event. Also bump the schema minor version, as this adds fields to an existing event. Signed-off-by: Mark Stemm --- driver/SCHEMA_VERSION | 2 +- driver/bpf/fillers.h | 19 ++++++++++++++ driver/event_table.c | 2 +- driver/fillers_table.c | 2 +- .../syscall_dispatched_events/fcntl.bpf.c | 8 ++++++ driver/ppm_fillers.c | 26 +++++++++++++++++++ driver/ppm_fillers.h | 1 + .../syscall_exit_suite/fcntl_x.cpp | 8 +++++- 8 files changed, 64 insertions(+), 4 deletions(-) diff --git a/driver/SCHEMA_VERSION b/driver/SCHEMA_VERSION index 834f2629538..c8e38b61405 100644 --- a/driver/SCHEMA_VERSION +++ b/driver/SCHEMA_VERSION @@ -1 +1 @@ -2.8.0 +2.9.0 diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 64a34616e5f..74fa2fe0e22 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -1018,6 +1018,25 @@ FILLER(sys_fcntl_e, true) return bpf_push_u8_to_ring(data, fcntl_cmd_to_scap(cmd)); } +FILLER(sys_fcntl_x, true) +{ + long retval; + + /* Parameter 1: Return Value */ + retval = bpf_syscall_get_retval(data->ctx); + int res = bpf_push_s64_to_ring(data, (s64)retval); + CHECK_RES(res); + + /* Parameter 2: fd (type: PT_FD) */ + s32 fd = (s32)bpf_syscall_get_argument(data, 0); + res = bpf_push_s64_to_ring(data, (s64)fd); + CHECK_RES(res); + + /* Parameter 3: cmd (type: PT_ENUMFLAGS8) */ + s32 cmd = (s32)bpf_syscall_get_argument(data, 1); + return bpf_push_u8_to_ring(data, fcntl_cmd_to_scap(cmd)); +} + FILLER(sys_access_e, true) { /* Parameter 1: mode (type: PT_UINT32) */ diff --git a/driver/event_table.c b/driver/event_table.c index c26028b704e..8c2078793bb 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -200,7 +200,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_DROP_E] = {"drop", EC_INTERNAL | EC_METAEVENT, EF_SKIPPARSERESET, 1, {{"ratio", PT_UINT32, PF_DEC} } }, [PPME_DROP_X] = {"drop", EC_INTERNAL | EC_METAEVENT, EF_SKIPPARSERESET, 1, {{"ratio", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_FCNTL_E] = {"fcntl", EC_IO_OTHER | EC_SYSCALL, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"fd", PT_FD, PF_DEC}, {"cmd", PT_ENUMFLAGS8, PF_DEC, fcntl_commands} } }, - [PPME_SYSCALL_FCNTL_X] = {"fcntl", EC_IO_OTHER | EC_SYSCALL, EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, + [PPME_SYSCALL_FCNTL_X] = {"fcntl", EC_IO_OTHER | EC_SYSCALL, EF_USES_FD | EF_MODIFIES_STATE, 3, {{"res", PT_FD, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"cmd", PT_ENUMFLAGS8, PF_DEC, fcntl_commands} } }, [PPME_SCHEDSWITCH_6_E] = {"switch", EC_SCHEDULER | EC_TRACEPOINT, EF_NONE, 6, {{"next", PT_PID, PF_DEC}, {"pgft_maj", PT_UINT64, PF_DEC}, {"pgft_min", PT_UINT64, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, /// TODO: do we need SKIPPARSERESET flag? [PPME_SCHEDSWITCH_6_X] = {"NA", EC_UNKNOWN, EF_UNUSED, 0}, [PPME_SYSCALL_EXECVE_13_E] = {"execve", EC_PROCESS | EC_SYSCALL, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, diff --git a/driver/fillers_table.c b/driver/fillers_table.c index e33804992d0..6caf9511acd 100644 --- a/driver/fillers_table.c +++ b/driver/fillers_table.c @@ -152,7 +152,7 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = { [PPME_DROP_E] = {FILLER_REF(sched_drop)}, [PPME_DROP_X] = {FILLER_REF(sched_drop)}, [PPME_SYSCALL_FCNTL_E] = {FILLER_REF(sys_fcntl_e)}, - [PPME_SYSCALL_FCNTL_X] = {FILLER_REF(sys_single_x)}, + [PPME_SYSCALL_FCNTL_X] = {FILLER_REF(sys_fcntl_x)}, #ifdef CAPTURE_CONTEXT_SWITCHES [PPME_SCHEDSWITCH_6_E] = {FILLER_REF(sched_switch_e)}, #endif diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fcntl.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fcntl.bpf.c index 3d569034138..724e4df1d09 100644 --- a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fcntl.bpf.c +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/fcntl.bpf.c @@ -81,6 +81,14 @@ int BPF_PROG(fcntl_x, /* Parameter 1: res (type: PT_FD)*/ 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: cmd (type: PT_ENUMFLAGS8) */ + int cmd = (s32)extract__syscall_argument(regs, 1); + ringbuf__store_u8(&ringbuf, fcntl_cmd_to_scap(cmd)); + /*=============================== COLLECT PARAMETERS ===========================*/ ringbuf__submit_event(&ringbuf); diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index c4f8cd60b13..43d8a56513c 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -4510,6 +4510,32 @@ int f_sys_fcntl_e(struct event_filler_arguments *args) return add_sentinel(args); } +int f_sys_fcntl_x(struct event_filler_arguments *args) +{ + int64_t retval; + unsigned long val = 0; + int res = 0; + s32 fd = 0; + + /* Parameter 1: return value */ + retval = (int64_t)(long)syscall_get_return_value(current, args->regs); + res = val_to_ring(args, retval, 0, false, 0); + CHECK_RES(res); + + /* Parameter 2: fd (type: PT_FD) */ + syscall_get_arguments_deprecated(args, 0, 1, &val); + fd = (s32)val; + res = val_to_ring(args, (s64)fd, 0, false, 0); + CHECK_RES(res); + + /* Parameter 3: cmd (type: PT_ENUMFLAGS8) */ + syscall_get_arguments_deprecated(args, 1, 1, &val); + res = val_to_ring(args, fcntl_cmd_to_scap(val), 0, false, 0); + CHECK_RES(res); + + return add_sentinel(args); +} + static inline int parse_ptrace_addr(struct event_filler_arguments *args, u16 request) { unsigned long val; diff --git a/driver/ppm_fillers.h b/driver/ppm_fillers.h index 377f6b3ed15..8f2d8b738ab 100644 --- a/driver/ppm_fillers.h +++ b/driver/ppm_fillers.h @@ -72,6 +72,7 @@ or GPL2.txt for full copies of the license. FN(sched_switch_e) \ FN(sched_drop) \ FN(sys_fcntl_e) \ + FN(sys_fcntl_x) \ FN(sys_ptrace_e) \ FN(sys_ptrace_x) \ FN(sys_mmap_e) \ diff --git a/test/drivers/test_suites/syscall_exit_suite/fcntl_x.cpp b/test/drivers/test_suites/syscall_exit_suite/fcntl_x.cpp index 39032d96d29..9e988193f6a 100644 --- a/test/drivers/test_suites/syscall_exit_suite/fcntl_x.cpp +++ b/test/drivers/test_suites/syscall_exit_suite/fcntl_x.cpp @@ -37,8 +37,14 @@ TEST(SyscallExit, fcntlX) /* Parameter 1: ret (type: PT_FD)*/ evt_test->assert_numeric_param(1, (int64_t)errno_value); + /* Parameter 2: fd (type: PT_FD) */ + evt_test->assert_numeric_param(2, (int64_t)invalid_fd); + + /* Parameter 3: cmd (type: PT_ENUMFLAGS8) */ + evt_test->assert_numeric_param(3, (uint8_t)PPM_FCNTL_F_DUPFD_CLOEXEC); + /*=============================== ASSERT PARAMETERS ===========================*/ - evt_test->assert_num_params_pushed(1); + evt_test->assert_num_params_pushed(3); } #endif