diff --git a/driver/bpf/fillers.h b/driver/bpf/fillers.h index 9fc889c44a..4605a6d89d 100644 --- a/driver/bpf/fillers.h +++ b/driver/bpf/fillers.h @@ -132,6 +132,7 @@ FILLER_RAW(terminate_filler) case PPME_SYSCALL_MKDIRAT_E: case PPME_SYSCALL_MOUNT_E: case PPME_SYSCALL_UMOUNT_E: + case PPME_SYSCALL_UMOUNT_1_E: case PPME_SYSCALL_RENAME_E: case PPME_SYSCALL_RENAMEAT_E: case PPME_SYSCALL_RENAMEAT2_E: @@ -214,6 +215,7 @@ FILLER_RAW(terminate_filler) case PPME_SYSCALL_MKDIRAT_X: case PPME_SYSCALL_MOUNT_X: case PPME_SYSCALL_UMOUNT_X: + case PPME_SYSCALL_UMOUNT_1_X: case PPME_SYSCALL_RENAME_X: case PPME_SYSCALL_RENAMEAT_X: case PPME_SYSCALL_RENAMEAT2_X: @@ -6137,6 +6139,18 @@ FILLER(sys_dup3_x, true) return res; } +FILLER(sys_umount_x, true) +{ + /* Parameter 1: ret (type: PT_FD) */ + long retval = bpf_syscall_get_retval(data->ctx); + int res = bpf_val_to_ring_type(data, retval, PT_ERRNO); + CHECK_RES(res); + + /* Parameter 2: name (type: PT_FSPATH) */ + unsigned long target_pointer = bpf_syscall_get_argument(data, 0); + return bpf_val_to_ring(data, target_pointer); +} + #ifdef CAPTURE_SCHED_PROC_EXEC /* We set `is_syscall` flag to `false` since this is not * a real syscall, we only send the same event from another diff --git a/driver/event_table.c b/driver/event_table.c index 245af18d00..8cdf56426b 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -270,7 +270,7 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_PPOLL_X] = {"ppoll", EC_WAIT | EC_SYSCALL, EF_WAITS, 2, {{"res", PT_ERRNO, PF_DEC}, {"fds", PT_FDLIST, PF_DEC} } }, [PPME_SYSCALL_MOUNT_E] = {"mount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 1, {{"flags", PT_FLAGS32, PF_HEX, mount_flags} } }, [PPME_SYSCALL_MOUNT_X] = {"mount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"dev", PT_CHARBUF, PF_NA}, {"dir", PT_FSPATH, PF_NA}, {"type", PT_CHARBUF, PF_NA} } }, - [PPME_SYSCALL_UMOUNT_E] = {"umount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 1, {{"flags", PT_FLAGS32, PF_HEX, umount_flags} } }, // we need to create separate events for umount and umount2, umount doesn't have the flag parameter!! + [PPME_SYSCALL_UMOUNT_E] = {"umount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 1, {{"flags", PT_FLAGS32, PF_HEX, umount_flags} } }, // right now this event pair is used by umount2 syscall, we need to create a new event pair `PPME_SYSCALL_UMOUNT2_E/PPME_SYSCALL_UMOUNT2_X` with name "umount2" we cannot change the name here otherwise we break scap-files compatibility. [PPME_SYSCALL_UMOUNT_X] = {"umount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"name", PT_FSPATH, PF_NA} } }, [PPME_K8S_E] = {"k8s", EC_INTERNAL | EC_METAEVENT, EF_SKIPPARSERESET | EF_MODIFIES_STATE, 1, {{"json", PT_CHARBUF, PF_NA} } }, [PPME_K8S_X] = {"NA", EC_UNKNOWN, EF_UNUSED, 0}, @@ -398,6 +398,8 @@ const struct ppm_event_info g_event_info[] = { [PPME_SYSCALL_FCHOWN_X] = {"fchown", EC_FILE | EC_SYSCALL, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } }, [PPME_SYSCALL_FCHOWNAT_E] = {"fchownat", EC_FILE | EC_SYSCALL, EF_NONE, 0}, [PPME_SYSCALL_FCHOWNAT_X] = {"fchownat", EC_FILE | EC_SYSCALL, EF_NONE, 6, {{"res", PT_ERRNO, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, fchownat_flags}} }, + [PPME_SYSCALL_UMOUNT_1_E] = {"umount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 0}, + [PPME_SYSCALL_UMOUNT_1_X] = {"umount", EC_FILE | EC_SYSCALL, EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"name", PT_FSPATH, PF_NA} } }, /* NB: Starting from scap version 1.2, event types will no longer be changed when an event is modified, and the only kind of change permitted for pre-existent events is adding parameters. * New event types are allowed only for new syscalls or new internal events. diff --git a/driver/fillers_table.c b/driver/fillers_table.c index c58a1d43b9..e5103e3ac3 100644 --- a/driver/fillers_table.c +++ b/driver/fillers_table.c @@ -340,4 +340,6 @@ const struct ppm_event_entry g_ppm_events[PPM_EVENT_MAX] = { [PPME_SYSCALL_FCHOWN_X] = {FILLER_REF(sys_fchown_x)}, [PPME_SYSCALL_FCHOWNAT_E] = {FILLER_REF(sys_empty)}, [PPME_SYSCALL_FCHOWNAT_X] = {FILLER_REF(sys_fchownat_x)}, + [PPME_SYSCALL_UMOUNT_1_E] = {FILLER_REF(sys_empty)}, + [PPME_SYSCALL_UMOUNT_1_X] = {FILLER_REF(sys_umount_x)}, }; diff --git a/driver/main.c b/driver/main.c index 6dc3374fc1..784f94d957 100644 --- a/driver/main.c +++ b/driver/main.c @@ -1475,6 +1475,7 @@ static inline void drops_buffer_syscall_categories_counters(ppm_event_code event case PPME_SYSCALL_MKDIRAT_E: case PPME_SYSCALL_MOUNT_E: case PPME_SYSCALL_UMOUNT_E: + case PPME_SYSCALL_UMOUNT_1_E: case PPME_SYSCALL_RENAME_E: case PPME_SYSCALL_RENAMEAT_E: case PPME_SYSCALL_RENAMEAT2_E: @@ -1545,6 +1546,7 @@ static inline void drops_buffer_syscall_categories_counters(ppm_event_code event case PPME_SYSCALL_MKDIRAT_X: case PPME_SYSCALL_MOUNT_X: case PPME_SYSCALL_UMOUNT_X: + case PPME_SYSCALL_UMOUNT_1_X: case PPME_SYSCALL_RENAME_X: case PPME_SYSCALL_RENAMEAT_X: case PPME_SYSCALL_RENAMEAT2_X: diff --git a/driver/modern_bpf/definitions/events_dimensions.h b/driver/modern_bpf/definitions/events_dimensions.h index 51941259b0..66fdbf3a88 100644 --- a/driver/modern_bpf/definitions/events_dimensions.h +++ b/driver/modern_bpf/definitions/events_dimensions.h @@ -103,6 +103,7 @@ #define UNSHARE_X_SIZE HEADER_LEN + sizeof(int64_t) + PARAM_LEN #define MOUNT_E_SIZE HEADER_LEN + sizeof(uint32_t) + PARAM_LEN #define UMOUNT2_E_SIZE HEADER_LEN + sizeof(uint32_t) + PARAM_LEN +#define UMOUNT_E_SIZE HEADER_LEN #define LINK_E_SIZE HEADER_LEN #define LINKAT_E_SIZE HEADER_LEN #define SYMLINK_E_SIZE HEADER_LEN diff --git a/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount.bpf.c b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount.bpf.c new file mode 100644 index 0000000000..bc26288ab7 --- /dev/null +++ b/driver/modern_bpf/programs/tail_called/events/syscall_dispatched_events/umount.bpf.c @@ -0,0 +1,72 @@ +/* + * 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 +#include + +/*=============================== ENTER EVENT ===========================*/ + +SEC("tp_btf/sys_enter") +int BPF_PROG(umount_e, + struct pt_regs *regs, + long id) +{ + struct ringbuf_struct ringbuf; + if(!ringbuf__reserve_space(&ringbuf, UMOUNT_E_SIZE)) + { + return 0; + } + + ringbuf__store_event_header(&ringbuf, PPME_SYSCALL_UMOUNT_1_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(umount_x, + struct pt_regs *regs, + long ret) +{ + struct auxiliary_map *auxmap = auxmap__get(); + if(!auxmap) + { + return 0; + } + + auxmap__preload_event_header(auxmap, PPME_SYSCALL_UMOUNT_1_X); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + /* Parameter 1: res (type: PT_ERRNO) */ + auxmap__store_s64_param(auxmap, ret); + + /* Parameter 2: name (type: PT_FSPATH) */ + unsigned long target_pointer = extract__syscall_argument(regs, 0); + auxmap__store_charbuf_param(auxmap, target_pointer, MAX_PATH, USER); + + /*=============================== COLLECT PARAMETERS ===========================*/ + + auxmap__finalize_event_header(auxmap); + + auxmap__submit_event(auxmap); + + return 0; +} + +/*=============================== EXIT EVENT ===========================*/ diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 2d7d21974b..9fc409cab2 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -1188,7 +1188,9 @@ typedef enum { PPME_SYSCALL_FCHOWN_X = 383, PPME_SYSCALL_FCHOWNAT_E = 384, PPME_SYSCALL_FCHOWNAT_X = 385, - PPM_EVENT_MAX = 386 + PPME_SYSCALL_UMOUNT_1_E = 386, + PPME_SYSCALL_UMOUNT_1_X = 387, + PPM_EVENT_MAX = 388 } ppm_event_code; /*@}*/ diff --git a/driver/ppm_fillers.c b/driver/ppm_fillers.c index c2e05ea952..c297ac751b 100644 --- a/driver/ppm_fillers.c +++ b/driver/ppm_fillers.c @@ -6985,6 +6985,25 @@ int f_sys_splice_e(struct event_filler_arguments *args) return add_sentinel(args); } +int f_sys_umount_x(struct event_filler_arguments *args) +{ + unsigned long val; + int res; + int64_t retval; + + /* Parameter 1: res (type: PT_ERRNO) */ + retval = (int64_t)syscall_get_return_value(current, args->regs); + res = val_to_ring(args, retval, 0, false, 0); + CHECK_RES(res); + + /* Parameter 2: name (type: PT_FSPATH) */ + syscall_get_arguments_deprecated(current, args->regs, 0, 1, &val); + res = val_to_ring(args, val, 0, true, 0); + CHECK_RES(res); + + return add_sentinel(args); +} + #ifdef CAPTURE_SCHED_PROC_EXEC int f_sched_prog_exec(struct event_filler_arguments *args) { diff --git a/driver/ppm_fillers.h b/driver/ppm_fillers.h index 92dbd7b948..6f53af454c 100644 --- a/driver/ppm_fillers.h +++ b/driver/ppm_fillers.h @@ -156,6 +156,7 @@ or GPL2.txt for full copies of the license. FN(sys_recvmsg_e) \ FN(sys_signalfd_e) \ FN(sys_splice_e) \ + FN(sys_umount_x) \ FN(terminate_filler) #define FILLER_ENUM_FN(x) PPM_FILLER_##x, diff --git a/driver/syscall_table.c b/driver/syscall_table.c index 9120a8f3c2..c1bbb38f42 100644 --- a/driver/syscall_table.c +++ b/driver/syscall_table.c @@ -425,7 +425,7 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { [__NR_lstat64 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_LSTAT64_E, PPME_SYSCALL_LSTAT64_X, PPM_SC_LSTAT64}, #endif #ifdef __NR_umount - [__NR_umount - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_UMOUNT_E, PPME_SYSCALL_UMOUNT_X, PPM_SC_UMOUNT}, + [__NR_umount - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_UMOUNT_1_E, PPME_SYSCALL_UMOUNT_1_X, PPM_SC_UMOUNT}, #endif #ifdef __NR_recv [__NR_recv - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_RECV_E, PPME_SOCKET_RECV_X, PPM_SC_RECV}, @@ -1238,7 +1238,7 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { [__NR_ia32_lstat64 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_LSTAT64_E, PPME_SYSCALL_LSTAT64_X, PPM_SC_LSTAT64}, #endif #ifdef __NR_ia32_umount - [__NR_ia32_umount - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_UMOUNT_E, PPME_SYSCALL_UMOUNT_X, PPM_SC_UMOUNT}, + [__NR_ia32_umount - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_UMOUNT_1_E, PPME_SYSCALL_UMOUNT_1_X, PPM_SC_UMOUNT}, #endif #ifdef __NR_ia32_recv [__NR_ia32_recv - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_RECV_E, PPME_SOCKET_RECV_X, PPM_SC_RECV}, diff --git a/test/drivers/test_suites/syscall_enter_suite/umount_e.cpp b/test/drivers/test_suites/syscall_enter_suite/umount_e.cpp new file mode 100644 index 0000000000..2b92b1ae1d --- /dev/null +++ b/test/drivers/test_suites/syscall_enter_suite/umount_e.cpp @@ -0,0 +1,39 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_umount + +TEST(SyscallEnter, umountE) +{ + auto evt_test = get_syscall_event_test(__NR_umount, ENTER_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + const char* target = "//**null-file-path**//"; + assert_syscall_state(SYSCALL_FAILURE, "umount", syscall(__NR_umount, target)); + + /*=============================== 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/umount_x.cpp b/test/drivers/test_suites/syscall_exit_suite/umount_x.cpp new file mode 100644 index 0000000000..02b232602b --- /dev/null +++ b/test/drivers/test_suites/syscall_exit_suite/umount_x.cpp @@ -0,0 +1,44 @@ +#include "../../event_class/event_class.h" + +#ifdef __NR_umount + +TEST(SyscallExit, umountX) +{ + auto evt_test = get_syscall_event_test(__NR_umount, EXIT_EVENT); + + evt_test->enable_capture(); + + /*=============================== TRIGGER SYSCALL ===========================*/ + + const char* target = "//**null-file-path**//"; + assert_syscall_state(SYSCALL_FAILURE, "umount", syscall(__NR_umount, target)); + 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: name (type: PT_FSPATH) */ + evt_test->assert_charbuf_param(2, target); + + /*=============================== 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 5364356dd5..aae3333b88 100644 --- a/userspace/libpman/src/events_prog_names.h +++ b/userspace/libpman/src/events_prog_names.h @@ -259,6 +259,8 @@ static const char* event_prog_names[PPM_EVENT_MAX] = { [PPME_SYSCALL_FCHOWN_X] = "fchown_x", [PPME_SYSCALL_FCHOWNAT_E] = "fchownat_e", [PPME_SYSCALL_FCHOWNAT_X] = "fchownat_x", + [PPME_SYSCALL_UMOUNT_1_E] = "umount_e", + [PPME_SYSCALL_UMOUNT_1_X] = "umount_x", }; /* Some events can require more than one bpf program to collect all the data. */ diff --git a/userspace/libsinsp/test/events_file.ut.cpp b/userspace/libsinsp/test/events_file.ut.cpp index 651898dd32..ab56f82ce4 100644 --- a/userspace/libsinsp/test/events_file.ut.cpp +++ b/userspace/libsinsp/test/events_file.ut.cpp @@ -183,3 +183,17 @@ TEST_F(sinsp_with_test_input, creates_fd_generic) ASSERT_EQ(get_field_as_string(evt, "fd.num"), "4"); } +TEST_F(sinsp_with_test_input, umount) +{ + add_default_init_thread(); + + open_inspector(); + sinsp_evt* evt = NULL; + + add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_UMOUNT_1_E, 0); + evt = add_event_advance_ts(increasing_ts(), 1, PPME_SYSCALL_UMOUNT_1_X, 2, 0, "/target_name"); + ASSERT_EQ(get_field_as_string(evt, "evt.type"), "umount"); + ASSERT_EQ(get_field_as_string(evt, "evt.category"), "file"); + ASSERT_EQ(get_field_as_string(evt, "evt.arg.res"), "0"); + ASSERT_EQ(get_field_as_string(evt, "evt.arg.name"), "/target_name"); +} diff --git a/userspace/libsinsp/test/table/event_table.cpp b/userspace/libsinsp/test/table/event_table.cpp index e2db3c5631..f15330e012 100644 --- a/userspace/libsinsp/test/table/event_table.cpp +++ b/userspace/libsinsp/test/table/event_table.cpp @@ -2,7 +2,7 @@ #include /* These numbers must be updated when we add new events */ -#define SYSCALL_EVENTS_NUM 340 +#define SYSCALL_EVENTS_NUM 342 #define TRACEPOINT_EVENTS_NUM 6 #define METAEVENTS_NUM 19 #define PLUGIN_EVENTS_NUM 1