Skip to content

Commit

Permalink
Add fcntl enter arguments to exit event
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mstemm committed Aug 22, 2023
1 parent 6caaa3c commit 063db0a
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 5 deletions.
2 changes: 1 addition & 1 deletion driver/SCHEMA_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.8.0
2.9.0
19 changes: 19 additions & 0 deletions driver/bpf/fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
Expand Down
2 changes: 1 addition & 1 deletion driver/event_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
2 changes: 1 addition & 1 deletion driver/fillers_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion driver/modern_bpf/definitions/events_dimensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
#define PREAD64_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + sizeof(uint64_t) + PARAM_LEN * 3
#define RECVFROM_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint32_t) + PARAM_LEN * 2
#define FCNTL_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint8_t) + PARAM_LEN * 2
#define FCNTL_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN
#define FCNTL_X_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(int64_t) + sizeof(uint8_t) + PARAM_LEN * 3
#define SHUTDOWN_E_SIZE HEADER_LEN + sizeof(int64_t) + sizeof(uint8_t) + PARAM_LEN * 2
#define SHUTDOWN_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN
#define FSCONFIG_E_SIZE HEADER_LEN
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
26 changes: 26 additions & 0 deletions driver/ppm_fillers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions driver/ppm_fillers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down
8 changes: 7 additions & 1 deletion test/drivers/test_suites/syscall_exit_suite/fcntl_x.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 063db0a

Please sign in to comment.