From a4262feb5053d28982951022b37a06e5870f99dd Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Mon, 1 Aug 2022 12:25:53 +0200 Subject: [PATCH 01/29] cleanup(driver,userspace/libscap,userspace/libsinsp): dropped simpleconsumer mode and simple driver concepts. Instead, clients should always push interesting syscalls set using new sinsp APIs: ``` void set_syscalls_of_interest(std::unordered_set &syscalls_of_interest); void mark_syscall_of_interest(uint32_t ppm_sc, bool enabled = true); ``` Moreover, moved bpf interesting syscall check as soon as possible. A new map was created to hold interesting syscalls for bpf. Finally, dropped EF_DROP_SIMPLE_CONS and UF_SIMPLEDRIVER_KEEP flags. Signed-off-by: Federico Di Pierro Co-authored-by: Andrea Terzolo --- driver/bpf/maps.h | 7 + driver/bpf/plumbing_helpers.h | 11 + driver/bpf/probe.c | 20 +- driver/bpf/types.h | 3 +- driver/event_table.c | 266 +++++++------- driver/main.c | 32 -- driver/ppm_events_public.h | 8 +- driver/syscall_table.c | 64 ++-- userspace/libscap/engine/bpf/scap_bpf.c | 53 ++- userspace/libscap/engine/kmod/scap_kmod.c | 20 +- userspace/libscap/engine/udig/scap_udig.c | 8 - .../libscap/examples/01-open/scap_open.c | 36 +- userspace/libscap/scap.c | 16 - userspace/libscap/scap.h | 3 - userspace/libscap/scap_engine_util.c | 7 +- userspace/libscap/scap_engine_util.h | 2 +- userspace/libscap/scap_vtable.h | 5 - userspace/libscap/syscall_info_table.c | 338 +++++++++--------- userspace/libsinsp/sinsp.cpp | 51 +-- userspace/libsinsp/sinsp.h | 13 +- 20 files changed, 429 insertions(+), 534 deletions(-) diff --git a/driver/bpf/maps.h b/driver/bpf/maps.h index 1031358ba5..52434999f6 100644 --- a/driver/bpf/maps.h +++ b/driver/bpf/maps.h @@ -99,6 +99,13 @@ struct bpf_map_def __bpf_section("maps") stash_map = { }; #endif +struct bpf_map_def __bpf_section("maps") interesting_syscalls_table = { + .type = BPF_MAP_TYPE_ARRAY, + .key_size = sizeof(u32), + .value_size = sizeof(bool), + .max_entries = SYSCALL_TABLE_SIZE, +}; + #endif // __KERNEL__ #endif diff --git a/driver/bpf/plumbing_helpers.h b/driver/bpf/plumbing_helpers.h index fd5ef037fb..cf27afc03b 100644 --- a/driver/bpf/plumbing_helpers.h +++ b/driver/bpf/plumbing_helpers.h @@ -284,6 +284,17 @@ static __always_inline const struct syscall_evt_pair *get_syscall_info(int id) return p; } +static __always_inline bool is_syscall_interesting(int id) +{ + bool *enabled = bpf_map_lookup_elem(&interesting_syscalls_table, &id); + + if (!enabled) + + bpf_printk("no syscall_info for %d\n", id); + + return enabled && *enabled; +} + static __always_inline const struct ppm_event_info *get_event_info(enum ppm_event_type event_type) { const struct ppm_event_info *e = diff --git a/driver/bpf/probe.c b/driver/bpf/probe.c index 18292f4396..91bea0685b 100644 --- a/driver/bpf/probe.c +++ b/driver/bpf/probe.c @@ -40,6 +40,7 @@ BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args) enum ppm_event_type evt_type; int drop_flags; long id; + bool enabled; if (bpf_in_ia32_syscall()) return 0; @@ -48,6 +49,12 @@ BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args) if (id < 0 || id >= SYSCALL_TABLE_SIZE) return 0; + enabled = is_syscall_interesting(id); + if (enabled == false) + { + return 0; + } + settings = get_bpf_settings(); if (!settings) return 0; @@ -59,9 +66,6 @@ BPF_PROBE("raw_syscalls/", sys_enter, sys_enter_args) if (!sc_evt) return 0; - if (sc_evt->flags & UF_UNINTERESTING) - return 0; - if (sc_evt->flags & UF_USED) { evt_type = sc_evt->enter_event_type; drop_flags = sc_evt->flags; @@ -92,6 +96,7 @@ BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args) enum ppm_event_type evt_type; int drop_flags; long id; + bool enabled; if (bpf_in_ia32_syscall()) return 0; @@ -100,6 +105,12 @@ BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args) if (id < 0 || id >= SYSCALL_TABLE_SIZE) return 0; + enabled = is_syscall_interesting(id); + if (enabled == false) + { + return 0; + } + settings = get_bpf_settings(); if (!settings) return 0; @@ -111,9 +122,6 @@ BPF_PROBE("raw_syscalls/", sys_exit, sys_exit_args) if (!sc_evt) return 0; - if (sc_evt->flags & UF_UNINTERESTING) - return 0; - if (sc_evt->flags & UF_USED) { evt_type = sc_evt->exit_event_type; drop_flags = sc_evt->flags; diff --git a/driver/bpf/types.h b/driver/bpf/types.h index fe225bb970..ea5c827e8f 100644 --- a/driver/bpf/types.h +++ b/driver/bpf/types.h @@ -220,8 +220,9 @@ enum scap_map_types { SCAP_TMP_SCRATCH_MAP = 7, SCAP_SETTINGS_MAP = 8, SCAP_LOCAL_STATE_MAP = 9, + SCAP_INTERESTING_SYSCALLS_TABLE = 10, #ifndef BPF_SUPPORTS_RAW_TRACEPOINTS - SCAP_STASH_MAP = 10, + SCAP_STASH_MAP = 11, #endif }; diff --git a/driver/event_table.c b/driver/event_table.c index 63c85f1bdf..e347aedde6 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -14,12 +14,12 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_GENERIC_X */{"syscall", EC_OTHER, EF_NONE, 1, {{"ID", PT_SYSCALLID, PF_DEC} } }, /* PPME_SYSCALL_OPEN_E */{"open", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT} } }, /* PPME_SYSCALL_OPEN_X */{"open", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_CLOSE_E */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_DEC} } }, - /* PPME_SYSCALL_CLOSE_X */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_READ_E */{"read", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_READ_X */{"read", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SYSCALL_WRITE_E */{"write", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_WRITE_X */{"write", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_CLOSE_E */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, + /* PPME_SYSCALL_CLOSE_X */{"close", EC_IO_OTHER, EF_DESTROYS_FD | EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_READ_E */{"read", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_READ_X */{"read", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_WRITE_E */{"write", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_WRITE_X */{"write", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, /* PPME_SYSCALL_BRK_1_E */{"brk", EC_MEMORY, EF_OLD_VERSION, 1, {{"size", PT_UINT32, PF_DEC} } }, /* PPME_SYSCALL_BRK_1_X */{"brk", EC_MEMORY, EF_OLD_VERSION, 1, {{"res", PT_UINT64, PF_HEX} } }, /* PPME_SYSCALL_EXECVE_8_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, @@ -38,73 +38,73 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SOCKET_LISTEN_X */{"listen", EC_NET, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SOCKET_ACCEPT_E */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, /* PPME_SOCKET_ACCEPT_X */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } }, - /* PPME_SYSCALL_SEND_E */{"send", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_SEND_X */{"send", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_SEND_E */{"send", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_SEND_X */{"send", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, /* PPME_SOCKET_SENDTO_E */{"sendto", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_MODIFIES_STATE, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA} } }, /* PPME_SOCKET_SENDTO_X */{"sendto", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SOCKET_RECV_E */{"recv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, - /* PPME_SOCKET_RECV_X */{"recv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SOCKET_RECV_E */{"recv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, + /* PPME_SOCKET_RECV_X */{"recv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, /* PPME_SOCKET_RECVFROM_E */{"recvfrom", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, /* PPME_SOCKET_RECVFROM_X */{"recvfrom", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 3, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA}, {"tuple", PT_SOCKTUPLE, PF_NA} } }, - /* PPME_SOCKET_SHUTDOWN_E */{"shutdown", EC_NET, EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"how", PT_ENUMFLAGS8, PF_HEX, shutdown_how} } }, - /* PPME_SOCKET_SHUTDOWN_X */{"shutdown", EC_NET, EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SOCKET_GETSOCKNAME_E */{"getsockname", EC_NET, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SOCKET_GETSOCKNAME_X */{"getsockname", EC_NET, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SOCKET_GETPEERNAME_E */{"getpeername", EC_NET, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SOCKET_GETPEERNAME_X */{"getpeername", EC_NET, EF_DROP_SIMPLE_CONS, 0}, + /* PPME_SOCKET_SHUTDOWN_E */{"shutdown", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 2, {{"fd", PT_FD, PF_DEC}, {"how", PT_ENUMFLAGS8, PF_HEX, shutdown_how} } }, + /* PPME_SOCKET_SHUTDOWN_X */{"shutdown", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SOCKET_GETSOCKNAME_E */{"getsockname", EC_NET, EF_NONE, 0}, + /* PPME_SOCKET_GETSOCKNAME_X */{"getsockname", EC_NET, EF_NONE, 0}, + /* PPME_SOCKET_GETPEERNAME_E */{"getpeername", EC_NET, EF_NONE, 0}, + /* PPME_SOCKET_GETPEERNAME_X */{"getpeername", EC_NET, EF_NONE, 0}, /* PPME_SOCKET_SOCKETPAIR_E */{"socketpair", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"domain", PT_ENUMFLAGS32, PF_DEC, socket_families}, {"type", PT_UINT32, PF_DEC}, {"proto", PT_UINT32, PF_DEC} } }, /* PPME_SOCKET_SOCKETPAIR_X */{"socketpair", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"source", PT_UINT64, PF_HEX}, {"peer", PT_UINT64, PF_HEX} } }, /* PPME_SOCKET_SETSOCKOPT_E */{"setsockopt", EC_NET, EF_NONE, 0 }, /* PPME_SOCKET_SETSOCKOPT_X */{"setsockopt", EC_NET, EF_USES_FD, 6, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"level", PT_ENUMFLAGS8, PF_DEC, sockopt_levels}, {"optname", PT_ENUMFLAGS8, PF_DEC, sockopt_options}, {"val", PT_DYN, PF_DEC, sockopt_dynamic_param, PPM_SOCKOPT_IDX_MAX}, {"optlen", PT_UINT32, PF_DEC}}}, - /* PPME_SOCKET_GETSOCKOPT_E */{"getsockopt", EC_NET, EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 0 }, - /* PPME_SOCKET_GETSOCKOPT_X */{"getsockopt", EC_NET, EF_USES_FD | EF_MODIFIES_STATE| EF_DROP_SIMPLE_CONS, 6, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"level", PT_ENUMFLAGS8, PF_DEC, sockopt_levels}, {"optname", PT_ENUMFLAGS8, PF_DEC, sockopt_options}, {"val", PT_DYN, PF_DEC, sockopt_dynamic_param, PPM_SOCKOPT_IDX_MAX}, {"optlen", PT_UINT32, PF_DEC}}}, + /* PPME_SOCKET_GETSOCKOPT_E */{"getsockopt", EC_NET, EF_MODIFIES_STATE, 0 }, + /* PPME_SOCKET_GETSOCKOPT_X */{"getsockopt", EC_NET, EF_USES_FD | EF_MODIFIES_STATE, 6, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"level", PT_ENUMFLAGS8, PF_DEC, sockopt_levels}, {"optname", PT_ENUMFLAGS8, PF_DEC, sockopt_options}, {"val", PT_DYN, PF_DEC, sockopt_dynamic_param, PPM_SOCKOPT_IDX_MAX}, {"optlen", PT_UINT32, PF_DEC}}}, /* PPME_SOCKET_SENDMSG_E */{"sendmsg", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_MODIFIES_STATE, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA} } }, /* PPME_SOCKET_SENDMSG_X */{"sendmsg", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SOCKET_SENDMMSG_E */{"sendmmsg", EC_IO_WRITE, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SOCKET_SENDMMSG_X */{"sendmmsg", EC_IO_WRITE, EF_DROP_SIMPLE_CONS, 0}, + /* PPME_SOCKET_SENDMMSG_E */{"sendmmsg", EC_IO_WRITE, EF_NONE, 0}, + /* PPME_SOCKET_SENDMMSG_X */{"sendmmsg", EC_IO_WRITE, EF_NONE, 0}, /* PPME_SOCKET_RECVMSG_E */{"recvmsg", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 1, {{"fd", PT_FD, PF_DEC} } }, /* PPME_SOCKET_RECVMSG_X */{"recvmsg", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA}, {"tuple", PT_SOCKTUPLE, PF_NA} } }, - /* PPME_SOCKET_RECVMMSG_E */{"recvmmsg", EC_IO_READ, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SOCKET_RECVMMSG_X */{"recvmmsg", EC_IO_READ, EF_DROP_SIMPLE_CONS, 0}, + /* PPME_SOCKET_RECVMMSG_E */{"recvmmsg", EC_IO_READ, EF_NONE, 0}, + /* PPME_SOCKET_RECVMMSG_X */{"recvmmsg", EC_IO_READ, EF_NONE, 0}, /* PPME_SOCKET_ACCEPT4_E */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"flags", PT_INT32, PF_HEX} } }, /* PPME_SOCKET_ACCEPT4_X */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 3, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC} } }, /* PPME_SYSCALL_CREAT_E */{"creat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT} } }, /* PPME_SYSCALL_CREAT_X */{"creat", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"fd", PT_FD, PF_DEC}, {"name", PT_FSPATH, PF_NA}, {"mode", PT_UINT32, PF_OCT}, {"dev", PT_UINT32, PF_HEX}, {"ino", PT_UINT64, PF_DEC} } }, /* PPME_SYSCALL_PIPE_E */{"pipe", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, /* PPME_SYSCALL_PIPE_X */{"pipe", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"fd1", PT_FD, PF_DEC}, {"fd2", PT_FD, PF_DEC}, {"ino", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_EVENTFD_E */{"eventfd", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 2, {{"initval", PT_UINT64, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX} } }, - /* PPME_SYSCALL_EVENTFD_X */{"eventfd", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_FD, PF_DEC} } }, - /* PPME_SYSCALL_FUTEX_E */{"futex", EC_IPC, EF_DROP_SIMPLE_CONS, 3, {{"addr", PT_UINT64, PF_HEX}, {"op", PT_ENUMFLAGS16, PF_HEX, futex_operations}, {"val", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_FUTEX_X */{"futex", EC_IPC, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_STAT_E */{"stat", EC_FILE, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_STAT_X */{"stat", EC_FILE, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, - /* PPME_SYSCALL_LSTAT_E */{"lstat", EC_FILE, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_LSTAT_X */{"lstat", EC_FILE, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, - /* PPME_SYSCALL_FSTAT_E */{"fstat", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_NA} } }, - /* PPME_SYSCALL_FSTAT_X */{"fstat", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_STAT64_E */{"stat64", EC_FILE, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_STAT64_X */{"stat64", EC_FILE, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, - /* PPME_SYSCALL_LSTAT64_E */{"lstat64", EC_FILE, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_LSTAT64_X */{"lstat64", EC_FILE, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, - /* PPME_SYSCALL_FSTAT64_E */{"fstat64", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_NA} } }, - /* PPME_SYSCALL_FSTAT64_X */{"fstat64", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_EPOLLWAIT_E */{"epoll_wait", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 1, {{"maxevents", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_EPOLLWAIT_X */{"epoll_wait", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_POLL_E */{"poll", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 2, {{"fds", PT_FDLIST, PF_DEC}, {"timeout", PT_INT64, PF_DEC} } }, - /* PPME_SYSCALL_POLL_X */{"poll", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"fds", PT_FDLIST, PF_DEC} } }, - /* PPME_SYSCALL_SELECT_E */{"select", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_SELECT_X */{"select", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_NEWSELECT_E */{"select", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_NEWSELECT_X */{"select", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_LSEEK_E */{"lseek", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 3, {{"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC}, {"whence", PT_ENUMFLAGS8, PF_DEC, lseek_whence} } }, - /* PPME_SYSCALL_LSEEK_X */{"lseek", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_LLSEEK_E */{"llseek", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 3, {{"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC}, {"whence", PT_ENUMFLAGS8, PF_DEC, lseek_whence} } }, - /* PPME_SYSCALL_LLSEEK_X */{"llseek", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_EVENTFD_E */{"eventfd", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"initval", PT_UINT64, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX} } }, + /* PPME_SYSCALL_EVENTFD_X */{"eventfd", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, + /* PPME_SYSCALL_FUTEX_E */{"futex", EC_IPC, EF_NONE, 3, {{"addr", PT_UINT64, PF_HEX}, {"op", PT_ENUMFLAGS16, PF_HEX, futex_operations}, {"val", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_FUTEX_X */{"futex", EC_IPC, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_STAT_E */{"stat", EC_FILE, EF_NONE, 0}, + /* PPME_SYSCALL_STAT_X */{"stat", EC_FILE, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, + /* PPME_SYSCALL_LSTAT_E */{"lstat", EC_FILE, EF_NONE, 0}, + /* PPME_SYSCALL_LSTAT_X */{"lstat", EC_FILE, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, + /* PPME_SYSCALL_FSTAT_E */{"fstat", EC_FILE, EF_USES_FD, 1, {{"fd", PT_FD, PF_NA} } }, + /* PPME_SYSCALL_FSTAT_X */{"fstat", EC_FILE, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_STAT64_E */{"stat64", EC_FILE, EF_NONE, 0}, + /* PPME_SYSCALL_STAT64_X */{"stat64", EC_FILE, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, + /* PPME_SYSCALL_LSTAT64_E */{"lstat64", EC_FILE, EF_NONE, 0}, + /* PPME_SYSCALL_LSTAT64_X */{"lstat64", EC_FILE, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, + /* PPME_SYSCALL_FSTAT64_E */{"fstat64", EC_FILE, EF_USES_FD, 1, {{"fd", PT_FD, PF_NA} } }, + /* PPME_SYSCALL_FSTAT64_X */{"fstat64", EC_FILE, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_EPOLLWAIT_E */{"epoll_wait", EC_WAIT, EF_WAITS, 1, {{"maxevents", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_EPOLLWAIT_X */{"epoll_wait", EC_WAIT, EF_WAITS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_POLL_E */{"poll", EC_WAIT, EF_WAITS, 2, {{"fds", PT_FDLIST, PF_DEC}, {"timeout", PT_INT64, PF_DEC} } }, + /* PPME_SYSCALL_POLL_X */{"poll", EC_WAIT, EF_WAITS, 2, {{"res", PT_ERRNO, PF_DEC}, {"fds", PT_FDLIST, PF_DEC} } }, + /* PPME_SYSCALL_SELECT_E */{"select", EC_WAIT, EF_WAITS, 0}, + /* PPME_SYSCALL_SELECT_X */{"select", EC_WAIT, EF_WAITS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_NEWSELECT_E */{"select", EC_WAIT, EF_WAITS, 0}, + /* PPME_SYSCALL_NEWSELECT_X */{"select", EC_WAIT, EF_WAITS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_LSEEK_E */{"lseek", EC_FILE, EF_USES_FD, 3, {{"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC}, {"whence", PT_ENUMFLAGS8, PF_DEC, lseek_whence} } }, + /* PPME_SYSCALL_LSEEK_X */{"lseek", EC_FILE, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_LLSEEK_E */{"llseek", EC_FILE, EF_USES_FD, 3, {{"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC}, {"whence", PT_ENUMFLAGS8, PF_DEC, lseek_whence} } }, + /* PPME_SYSCALL_LLSEEK_X */{"llseek", EC_FILE, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_IOCTL_2_E */{"ioctl", EC_IO_OTHER, EF_USES_FD | EF_OLD_VERSION, 2, {{"fd", PT_FD, PF_DEC}, {"request", PT_UINT64, PF_HEX} } }, /* PPME_SYSCALL_IOCTL_2_X */{"ioctl", EC_IO_OTHER, EF_USES_FD | EF_OLD_VERSION, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_GETCWD_E */{"getcwd", EC_FILE, EF_DROP_SIMPLE_CONS, 0}, + /* PPME_SYSCALL_GETCWD_E */{"getcwd", EC_FILE, EF_NONE, 0}, /* Note: path is PT_CHARBUF and not PT_FSPATH because we assume it's absolute and will never need resolution */ - /* PPME_SYSCALL_GETCWD_X */{"getcwd", EC_FILE, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_CHARBUF, PF_NA} } }, + /* PPME_SYSCALL_GETCWD_X */{"getcwd", EC_FILE, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_CHARBUF, PF_NA} } }, /* Note: path is PT_CHARBUF and not PT_FSPATH because we don't want it to be resolved, since the event handler already changes it */ /* PPME_SYSCALL_CHDIR_E */{"chdir", EC_FILE, EF_MODIFIES_STATE, 0}, /* PPME_SYSCALL_CHDIR_X */{"chdir", EC_FILE, EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_CHARBUF, PF_NA} } }, @@ -124,18 +124,18 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_UNLINK_X */{"unlink", EC_FILE, EF_OLD_VERSION, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_UNLINKAT_E */{"unlinkat", EC_FILE, EF_OLD_VERSION, 2, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_CHARBUF, PF_NA} } }, /* PPME_SYSCALL_UNLINKAT_X */{"unlinkat", EC_FILE, EF_OLD_VERSION, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_PREAD_E */{"pread", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_PREAD_X */{"pread", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SYSCALL_PWRITE_E */{"pwrite", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_PWRITE_X */{"pwrite", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SYSCALL_READV_E */{"readv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_DEC} } }, - /* PPME_SYSCALL_READV_X */{"readv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 3, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SYSCALL_WRITEV_E */{"writev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_WRITEV_X */{"writev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SYSCALL_PREADV_E */{"preadv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_PREADV_X */{"preadv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD | EF_DROP_SIMPLE_CONS, 3, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, - /* PPME_SYSCALL_PWRITEV_E */{"pwritev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_PWRITEV_X */{"pwritev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_PREAD_E */{"pread", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_PREAD_X */{"pread", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_PWRITE_E */{"pwrite", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_PWRITE_X */{"pwrite", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_READV_E */{"readv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 1, {{"fd", PT_FD, PF_DEC} } }, + /* PPME_SYSCALL_READV_X */{"readv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 3, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_WRITEV_E */{"writev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_WRITEV_X */{"writev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_PREADV_E */{"preadv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 2, {{"fd", PT_FD, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_PREADV_X */{"preadv", EC_IO_READ, EF_USES_FD | EF_READS_FROM_FD, 3, {{"res", PT_ERRNO, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, + /* PPME_SYSCALL_PWRITEV_E */{"pwritev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 3, {{"fd", PT_FD, PF_DEC}, {"size", PT_UINT32, PF_DEC}, {"pos", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_PWRITEV_X */{"pwritev", EC_IO_WRITE, EF_USES_FD | EF_WRITES_TO_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"data", PT_BYTEBUF, PF_NA} } }, /* PPME_SYSCALL_DUP_E */{"dup", EC_IO_OTHER, EF_CREATES_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"fd", PT_FD, PF_DEC} } }, /* PPME_SYSCALL_DUP_X */{"dup", EC_IO_OTHER, EF_CREATES_FD | EF_USES_FD | EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"res", PT_FD, PF_DEC} } }, /* PPME_SYSCALL_SIGNALFD_E */{"signalfd", EC_SIGNAL, EF_CREATES_FD | EF_MODIFIES_STATE, 3, {{"fd", PT_FD, PF_DEC}, {"mask", PT_UINT32, PF_HEX}, {"flags", PT_FLAGS8, PF_HEX} } }, @@ -146,40 +146,40 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_TKILL_X */{"tkill", EC_SIGNAL, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_TGKILL_E */{"tgkill", EC_SIGNAL, EF_NONE, 3, {{"pid", PT_PID, PF_DEC}, {"tid", PT_PID, PF_DEC}, {"sig", PT_SIGTYPE, PF_DEC} } }, /* PPME_SYSCALL_TGKILL_X */{"tgkill", EC_SIGNAL, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_NANOSLEEP_E */{"nanosleep", EC_SLEEP, EF_WAITS | EF_DROP_SIMPLE_CONS, 1, {{"interval", PT_RELTIME, PF_DEC} } }, - /* PPME_SYSCALL_NANOSLEEP_X */{"nanosleep", EC_SLEEP, EF_WAITS | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_TIMERFD_CREATE_E */{"timerfd_create", EC_TIME, EF_CREATES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 2, {{"clockid", PT_UINT8, PF_DEC}, {"flags", PT_FLAGS8, PF_HEX} } }, - /* PPME_SYSCALL_TIMERFD_CREATE_X */{"timerfd_create", EC_TIME, EF_CREATES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_FD, PF_DEC} } }, + /* PPME_SYSCALL_NANOSLEEP_E */{"nanosleep", EC_SLEEP, EF_WAITS, 1, {{"interval", PT_RELTIME, PF_DEC} } }, + /* PPME_SYSCALL_NANOSLEEP_X */{"nanosleep", EC_SLEEP, EF_WAITS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_TIMERFD_CREATE_E */{"timerfd_create", EC_TIME, EF_CREATES_FD | EF_MODIFIES_STATE, 2, {{"clockid", PT_UINT8, PF_DEC}, {"flags", PT_FLAGS8, PF_HEX} } }, + /* PPME_SYSCALL_TIMERFD_CREATE_X */{"timerfd_create", EC_TIME, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, /* PPME_SYSCALL_INOTIFY_INIT_E */{"inotify_init", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"flags", PT_FLAGS8, PF_HEX} } }, /* PPME_SYSCALL_INOTIFY_INIT_X */{"inotify_init", EC_IPC, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, - /* PPME_SYSCALL_GETRLIMIT_E */{"getrlimit", EC_PROCESS, EF_DROP_SIMPLE_CONS, 1, {{"resource", PT_ENUMFLAGS8, PF_DEC, rlimit_resources} } }, - /* PPME_SYSCALL_GETRLIMIT_X */{"getrlimit", EC_PROCESS, EF_DROP_SIMPLE_CONS, 3, {{"res", PT_ERRNO, PF_DEC}, {"cur", PT_INT64, PF_DEC}, {"max", PT_INT64, PF_DEC} } }, - /* PPME_SYSCALL_SETRLIMIT_E */{"setrlimit", EC_PROCESS, EF_DROP_SIMPLE_CONS, 1, {{"resource", PT_ENUMFLAGS8, PF_DEC, rlimit_resources} } }, - /* PPME_SYSCALL_SETRLIMIT_X */{"setrlimit", EC_PROCESS, EF_DROP_SIMPLE_CONS, 3, {{"res", PT_ERRNO, PF_DEC}, {"cur", PT_INT64, PF_DEC}, {"max", PT_INT64, PF_DEC} } }, + /* PPME_SYSCALL_GETRLIMIT_E */{"getrlimit", EC_PROCESS, EF_NONE, 1, {{"resource", PT_ENUMFLAGS8, PF_DEC, rlimit_resources} } }, + /* PPME_SYSCALL_GETRLIMIT_X */{"getrlimit", EC_PROCESS, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"cur", PT_INT64, PF_DEC}, {"max", PT_INT64, PF_DEC} } }, + /* PPME_SYSCALL_SETRLIMIT_E */{"setrlimit", EC_PROCESS, EF_NONE, 1, {{"resource", PT_ENUMFLAGS8, PF_DEC, rlimit_resources} } }, + /* PPME_SYSCALL_SETRLIMIT_X */{"setrlimit", EC_PROCESS, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"cur", PT_INT64, PF_DEC}, {"max", PT_INT64, PF_DEC} } }, /* PPME_SYSCALL_PRLIMIT_E */{"prlimit", EC_PROCESS, EF_NONE, 2, {{"pid", PT_PID, PF_DEC}, {"resource", PT_ENUMFLAGS8, PF_DEC, rlimit_resources} } }, /* PPME_SYSCALL_PRLIMIT_X */{"prlimit", EC_PROCESS, EF_NONE, 5, {{"res", PT_ERRNO, PF_DEC}, {"newcur", PT_INT64, PF_DEC}, {"newmax", PT_INT64, PF_DEC}, {"oldcur", PT_INT64, PF_DEC}, {"oldmax", PT_INT64, PF_DEC} } }, - /* PPME_SCHEDSWITCH_1_E */{"switch", EC_SCHEDULER, EF_SKIPPARSERESET | EF_OLD_VERSION | EF_DROP_SIMPLE_CONS, 1, {{"next", PT_PID, PF_DEC} } }, + /* PPME_SCHEDSWITCH_1_E */{"switch", EC_SCHEDULER, EF_SKIPPARSERESET | EF_OLD_VERSION, 1, {{"next", PT_PID, PF_DEC} } }, /* PPME_SCHEDSWITCH_1_X */{"NA2", EC_SCHEDULER, EF_SKIPPARSERESET | EF_UNUSED | EF_OLD_VERSION, 0}, /* PPME_DROP_E */{"drop", EC_INTERNAL, EF_SKIPPARSERESET, 1, {{"ratio", PT_UINT32, PF_DEC} } }, /* PPME_DROP_X */{"drop", EC_INTERNAL, EF_SKIPPARSERESET, 1, {{"ratio", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_FCNTL_E */{"fcntl", EC_IO_OTHER, EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 2, {{"fd", PT_FD, PF_DEC}, {"cmd", PT_ENUMFLAGS8, PF_DEC, fcntl_commands} } }, - /* PPME_SYSCALL_FCNTL_X */{"fcntl", EC_IO_OTHER, EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_FD, PF_DEC} } }, - /* PPME_SCHEDSWITCH_6_E */{"switch", EC_SCHEDULER, EF_DROP_SIMPLE_CONS, 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} } }, + /* PPME_SYSCALL_FCNTL_E */{"fcntl", EC_IO_OTHER, 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, EF_USES_FD | EF_MODIFIES_STATE, 1, {{"res", PT_FD, PF_DEC} } }, + /* PPME_SCHEDSWITCH_6_E */{"switch", EC_SCHEDULER, 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} } }, /* PPME_SCHEDSWITCH_6_X */{"NA2", EC_SCHEDULER, EF_UNUSED, 0}, /* PPME_SYSCALL_EXECVE_13_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, /* PPME_SYSCALL_EXECVE_13_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 13, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, 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} } }, /* PPME_SYSCALL_CLONE_16_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, /* PPME_SYSCALL_CLONE_16_X */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 16, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, 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}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_BRK_4_E */{"brk", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"addr", PT_UINT64, PF_HEX} } }, - /* PPME_SYSCALL_BRK_4_X */{"brk", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_MMAP_E */{"mmap", EC_MEMORY, EF_DROP_SIMPLE_CONS, 6, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags}, {"flags", PT_FLAGS32, PF_HEX, mmap_flags}, {"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_MMAP_X */{"mmap", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_MMAP2_E */{"mmap2", EC_MEMORY, EF_DROP_SIMPLE_CONS, 6, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags}, {"flags", PT_FLAGS32, PF_HEX, mmap_flags}, {"fd", PT_FD, PF_DEC}, {"pgoffset", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_MMAP2_X */{"mmap2", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_MUNMAP_E */{"munmap", EC_MEMORY, EF_DROP_SIMPLE_CONS, 2, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_MUNMAP_X */{"munmap", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_SPLICE_E */{"splice", EC_IO_OTHER, EF_USES_FD | EF_DROP_SIMPLE_CONS, 4, {{"fd_in", PT_FD, PF_DEC}, {"fd_out", PT_FD, PF_DEC}, {"size", PT_UINT64, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, splice_flags} } }, - /* PPME_SYSCALL_SPLICE_X */{"splice", EC_IO_OTHER, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_BRK_4_E */{"brk", EC_MEMORY, EF_NONE, 1, {{"addr", PT_UINT64, PF_HEX} } }, + /* PPME_SYSCALL_BRK_4_X */{"brk", EC_MEMORY, EF_NONE, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_MMAP_E */{"mmap", EC_MEMORY, EF_NONE, 6, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags}, {"flags", PT_FLAGS32, PF_HEX, mmap_flags}, {"fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_MMAP_X */{"mmap", EC_MEMORY, EF_NONE, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_MMAP2_E */{"mmap2", EC_MEMORY, EF_NONE, 6, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags}, {"flags", PT_FLAGS32, PF_HEX, mmap_flags}, {"fd", PT_FD, PF_DEC}, {"pgoffset", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_MMAP2_X */{"mmap2", EC_MEMORY, EF_NONE, 4, {{"res", PT_UINT64, PF_HEX}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_MUNMAP_E */{"munmap", EC_MEMORY, EF_NONE, 2, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_MUNMAP_X */{"munmap", EC_MEMORY, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"vm_size", PT_UINT32, PF_DEC}, {"vm_rss", PT_UINT32, PF_DEC}, {"vm_swap", PT_UINT32, PF_DEC} } }, + /* PPME_SYSCALL_SPLICE_E */{"splice", EC_IO_OTHER, EF_USES_FD, 4, {{"fd_in", PT_FD, PF_DEC}, {"fd_out", PT_FD, PF_DEC}, {"size", PT_UINT64, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, splice_flags} } }, + /* PPME_SYSCALL_SPLICE_X */{"splice", EC_IO_OTHER, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_PTRACE_E */{"ptrace", EC_PROCESS, EF_NONE, 2, {{"request", PT_ENUMFLAGS16, PF_DEC, ptrace_requests}, {"pid", PT_PID, PF_DEC} } }, /* PPME_SYSCALL_PTRACE_X */{"ptrace", EC_PROCESS, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_DYN, PF_HEX, ptrace_dynamic_param, PPM_PTRACE_IDX_MAX}, {"data", PT_DYN, PF_HEX, ptrace_dynamic_param, PPM_PTRACE_IDX_MAX} } }, /* PPME_SYSCALL_IOCTL_3_E */{"ioctl", EC_IO_OTHER, EF_USES_FD, 3, {{"fd", PT_FD, PF_DEC}, {"request", PT_UINT64, PF_HEX}, {"argument", PT_UINT64, PF_HEX} } }, @@ -200,8 +200,8 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_VFORK_X */{"vfork", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 16, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, 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}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC} } }, /* PPME_PROCEXIT_1_E */{"procexit", EC_PROCESS, EF_MODIFIES_STATE, 4, {{"status", PT_ERRNO, PF_DEC}, {"ret", PT_ERRNO, PF_DEC}, {"sig", PT_SIGTYPE, PF_DEC}, {"core", PT_UINT8, PF_DEC} } }, /* PPME_NA1 */{"NA1", EC_PROCESS, EF_UNUSED, 0}, - /* PPME_SYSCALL_SENDFILE_E */{"sendfile", EC_IO_WRITE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 4, {{"out_fd", PT_FD, PF_DEC}, {"in_fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC}, {"size", PT_UINT64, PF_DEC} } }, - /* PPME_SYSCALL_SENDFILE_X */{"sendfile", EC_IO_WRITE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"offset", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_SENDFILE_E */{"sendfile", EC_IO_WRITE, EF_USES_FD, 4, {{"out_fd", PT_FD, PF_DEC}, {"in_fd", PT_FD, PF_DEC}, {"offset", PT_UINT64, PF_DEC}, {"size", PT_UINT64, PF_DEC} } }, + /* PPME_SYSCALL_SENDFILE_X */{"sendfile", EC_IO_WRITE, EF_USES_FD, 2, {{"res", PT_ERRNO, PF_DEC}, {"offset", PT_UINT64, PF_DEC} } }, /* PPME_SYSCALL_QUOTACTL_E */{"quotactl", EC_USER, EF_NONE, 4, {{"cmd", PT_FLAGS16, PF_DEC, quotactl_cmds }, {"type", PT_FLAGS8, PF_DEC, quotactl_types}, {"id", PT_UINT32, PF_DEC}, {"quota_fmt", PT_FLAGS8, PF_DEC, quotactl_quota_fmts } } }, /* PPME_SYSCALL_QUOTACTL_X */{"quotactl", EC_USER, EF_NONE, 14, {{"res", PT_ERRNO, PF_DEC}, {"special", PT_CHARBUF, PF_NA }, {"quotafilepath", PT_CHARBUF, PF_NA}, {"dqb_bhardlimit", PT_UINT64, PF_DEC }, {"dqb_bsoftlimit", PT_UINT64, PF_DEC }, {"dqb_curspace", PT_UINT64, PF_DEC }, {"dqb_ihardlimit", PT_UINT64, PF_DEC }, {"dqb_isoftlimit", PT_UINT64, PF_DEC }, {"dqb_btime", PT_RELTIME, PF_DEC }, {"dqb_itime", PT_RELTIME, PF_DEC }, {"dqi_bgrace", PT_RELTIME, PF_DEC }, {"dqi_igrace", PT_RELTIME, PF_DEC }, {"dqi_flags", PT_FLAGS8, PF_DEC, quotactl_dqi_flags }, {"quota_fmt_out", PT_FLAGS8, PF_DEC, quotactl_quota_fmts } } }, /* PPME_SYSCALL_SETRESUID_E */ {"setresuid", EC_USER, EF_MODIFIES_STATE, 3, {{"ruid", PT_UID, PF_DEC }, {"euid", PT_UID, PF_DEC }, {"suid", PT_UID, PF_DEC } } }, @@ -214,18 +214,18 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_SETUID_X */ {"setuid", EC_USER, EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_SETGID_E */ {"setgid", EC_USER, EF_MODIFIES_STATE, 1, {{"gid", PT_GID, PF_DEC} } }, /* PPME_SYSCALL_SETGID_X */ {"setgid", EC_USER, EF_MODIFIES_STATE, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_GETUID_E */ {"getuid", EC_USER, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_GETUID_X */ {"getuid", EC_USER, EF_DROP_SIMPLE_CONS, 1, {{"uid", PT_UID, PF_DEC} } }, - /* PPME_SYSCALL_GETEUID_E */ {"geteuid", EC_USER, EF_DROP_SIMPLE_CONS, 0 }, - /* PPME_SYSCALL_GETEUID_X */ {"geteuid", EC_USER, EF_DROP_SIMPLE_CONS, 1, {{"euid", PT_UID, PF_DEC} } }, - /* PPME_SYSCALL_GETGID_E */ {"getgid", EC_USER, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_GETGID_X */ {"getgid", EC_USER, EF_DROP_SIMPLE_CONS, 1, {{"gid", PT_GID, PF_DEC} } }, - /* PPME_SYSCALL_GETEGID_E */ {"getegid", EC_USER, EF_DROP_SIMPLE_CONS, 0 }, - /* PPME_SYSCALL_GETEGID_X */ {"getegid", EC_USER, EF_DROP_SIMPLE_CONS, 1, {{"egid", PT_GID, PF_DEC} } }, - /* PPME_SYSCALL_GETRESUID_E */ {"getresuid", EC_USER, EF_DROP_SIMPLE_CONS, 0 }, - /* PPME_SYSCALL_GETRESUID_X */ {"getresuid", EC_USER, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"ruid", PT_UID, PF_DEC }, {"euid", PT_UID, PF_DEC }, {"suid", PT_UID, PF_DEC } } }, - /* PPME_SYSCALL_GETRESGID_E */ {"getresgid", EC_USER, EF_DROP_SIMPLE_CONS, 0 }, - /* PPME_SYSCALL_GETRESGID_X */ {"getresgid", EC_USER, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"rgid", PT_GID, PF_DEC }, {"egid", PT_GID, PF_DEC }, {"sgid", PT_GID, PF_DEC } } }, + /* PPME_SYSCALL_GETUID_E */ {"getuid", EC_USER, EF_NONE, 0}, + /* PPME_SYSCALL_GETUID_X */ {"getuid", EC_USER, EF_NONE, 1, {{"uid", PT_UID, PF_DEC} } }, + /* PPME_SYSCALL_GETEUID_E */ {"geteuid", EC_USER, EF_NONE, 0 }, + /* PPME_SYSCALL_GETEUID_X */ {"geteuid", EC_USER, EF_NONE, 1, {{"euid", PT_UID, PF_DEC} } }, + /* PPME_SYSCALL_GETGID_E */ {"getgid", EC_USER, EF_NONE, 0}, + /* PPME_SYSCALL_GETGID_X */ {"getgid", EC_USER, EF_NONE, 1, {{"gid", PT_GID, PF_DEC} } }, + /* PPME_SYSCALL_GETEGID_E */ {"getegid", EC_USER, EF_NONE, 0 }, + /* PPME_SYSCALL_GETEGID_X */ {"getegid", EC_USER, EF_NONE, 1, {{"egid", PT_GID, PF_DEC} } }, + /* PPME_SYSCALL_GETRESUID_E */ {"getresuid", EC_USER, EF_NONE, 0 }, + /* PPME_SYSCALL_GETRESUID_X */ {"getresuid", EC_USER, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"ruid", PT_UID, PF_DEC }, {"euid", PT_UID, PF_DEC }, {"suid", PT_UID, PF_DEC } } }, + /* PPME_SYSCALL_GETRESGID_E */ {"getresgid", EC_USER, EF_NONE, 0 }, + /* PPME_SYSCALL_GETRESGID_X */ {"getresgid", EC_USER, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"rgid", PT_GID, PF_DEC }, {"egid", PT_GID, PF_DEC }, {"sgid", PT_GID, PF_DEC } } }, /* PPME_SYSCALL_EXECVE_15_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, /* PPME_SYSCALL_EXECVE_15_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 15, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, 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}, {"comm", PT_CHARBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA} } }, /* PPME_SYSCALL_CLONE_17_E */{"clone", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, @@ -244,14 +244,14 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_CONTAINER_X */{"container", EC_INTERNAL, EF_UNUSED | EF_OLD_VERSION, 0}, /* PPME_SYSCALL_EXECVE_16_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 0}, /* PPME_SYSCALL_EXECVE_16_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 16, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, 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}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA} } }, - /* PPME_SIGNALDELIVER_E */ {"signaldeliver", EC_SIGNAL, EF_DROP_SIMPLE_CONS, 3, {{"spid", PT_PID, PF_DEC}, {"dpid", PT_PID, PF_DEC}, {"sig", PT_SIGTYPE, PF_DEC} } }, + /* PPME_SIGNALDELIVER_E */ {"signaldeliver", EC_SIGNAL, EF_NONE, 3, {{"spid", PT_PID, PF_DEC}, {"dpid", PT_PID, PF_DEC}, {"sig", PT_SIGTYPE, PF_DEC} } }, /* PPME_SIGNALDELIVER_X */ {"signaldeliver", EC_SIGNAL, EF_UNUSED, 0 }, - /* PPME_PROCINFO_E */{"procinfo", EC_INTERNAL, EF_SKIPPARSERESET | EF_DROP_SIMPLE_CONS, 2, {{"cpu_usr", PT_UINT64, PF_DEC}, {"cpu_sys", PT_UINT64, PF_DEC} } }, + /* PPME_PROCINFO_E */{"procinfo", EC_INTERNAL, EF_SKIPPARSERESET, 2, {{"cpu_usr", PT_UINT64, PF_DEC}, {"cpu_sys", PT_UINT64, PF_DEC} } }, /* PPME_PROCINFO_X */{"NA2", EC_INTERNAL, EF_UNUSED, 0}, - /* PPME_SYSCALL_GETDENTS_E */{"getdents", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_NA} } }, - /* PPME_SYSCALL_GETDENTS_X */{"getdents", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_GETDENTS64_E */{"getdents64", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"fd", PT_FD, PF_NA} } }, - /* PPME_SYSCALL_GETDENTS64_X */{"getdents64", EC_FILE, EF_USES_FD | EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_GETDENTS_E */{"getdents", EC_FILE, EF_USES_FD, 1, {{"fd", PT_FD, PF_NA} } }, + /* PPME_SYSCALL_GETDENTS_X */{"getdents", EC_FILE, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_GETDENTS64_E */{"getdents64", EC_FILE, EF_USES_FD, 1, {{"fd", PT_FD, PF_NA} } }, + /* PPME_SYSCALL_GETDENTS64_X */{"getdents64", EC_FILE, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_SETNS_E */ {"setns", EC_PROCESS, EF_USES_FD, 2, {{"fd", PT_FD, PF_NA}, {"nstype", PT_FLAGS32, PF_HEX, clone_flags} } }, /* PPME_SYSCALL_SETNS_X */ {"setns", EC_PROCESS, EF_USES_FD, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_FLOCK_E */ {"flock", EC_FILE, EF_USES_FD, 2, {{"fd", PT_FD, PF_NA}, {"operation", PT_FLAGS32, PF_HEX, flock_flags} } }, @@ -262,22 +262,22 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SOCKET_ACCEPT_5_X */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC}, {"queuelen", PT_UINT32, PF_DEC}, {"queuemax", PT_UINT32, PF_DEC} } }, /* PPME_SOCKET_ACCEPT4_5_E */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 1, {{"flags", PT_INT32, PF_HEX} } }, /* PPME_SOCKET_ACCEPT4_5_X */{"accept", EC_NET, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"fd", PT_FD, PF_DEC}, {"tuple", PT_SOCKTUPLE, PF_NA}, {"queuepct", PT_UINT8, PF_DEC}, {"queuelen", PT_UINT32, PF_DEC}, {"queuemax", PT_UINT32, PF_DEC} } }, - /* PPME_SYSCALL_SEMOP_E */ {"semop", EC_PROCESS, EF_DROP_SIMPLE_CONS, 1, {{"semid", PT_INT32, PF_DEC} } }, - /* PPME_SYSCALL_SEMOP_X */ {"semop", EC_PROCESS, EF_DROP_SIMPLE_CONS, 8, {{"res", PT_ERRNO, PF_DEC}, {"nsops", PT_UINT32, PF_DEC}, {"sem_num_0", PT_UINT16, PF_DEC}, {"sem_op_0", PT_INT16, PF_DEC}, {"sem_flg_0", PT_FLAGS16, PF_HEX, semop_flags}, {"sem_num_1", PT_UINT16, PF_DEC}, {"sem_op_1", PT_INT16, PF_DEC}, {"sem_flg_1", PT_FLAGS16, PF_HEX, semop_flags} } }, - /* PPME_SYSCALL_SEMCTL_E */{"semctl", EC_PROCESS, EF_DROP_SIMPLE_CONS, 4, {{"semid", PT_INT32, PF_DEC}, {"semnum", PT_INT32, PF_DEC}, {"cmd", PT_FLAGS16, PF_HEX, semctl_commands}, {"val", PT_INT32, PF_DEC} } }, - /* PPME_SYSCALL_SEMCTL_X */{"semctl", EC_PROCESS, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_PPOLL_E */{"ppoll", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 3, {{"fds", PT_FDLIST, PF_DEC}, {"timeout", PT_RELTIME, PF_DEC}, {"sigmask", PT_SIGSET, PF_DEC} } }, - /* PPME_SYSCALL_PPOLL_X */{"ppoll", EC_WAIT, EF_WAITS | EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"fds", PT_FDLIST, PF_DEC} } }, + /* PPME_SYSCALL_SEMOP_E */ {"semop", EC_PROCESS, EF_NONE, 1, {{"semid", PT_INT32, PF_DEC} } }, + /* PPME_SYSCALL_SEMOP_X */ {"semop", EC_PROCESS, EF_NONE, 8, {{"res", PT_ERRNO, PF_DEC}, {"nsops", PT_UINT32, PF_DEC}, {"sem_num_0", PT_UINT16, PF_DEC}, {"sem_op_0", PT_INT16, PF_DEC}, {"sem_flg_0", PT_FLAGS16, PF_HEX, semop_flags}, {"sem_num_1", PT_UINT16, PF_DEC}, {"sem_op_1", PT_INT16, PF_DEC}, {"sem_flg_1", PT_FLAGS16, PF_HEX, semop_flags} } }, + /* PPME_SYSCALL_SEMCTL_E */{"semctl", EC_PROCESS, EF_NONE, 4, {{"semid", PT_INT32, PF_DEC}, {"semnum", PT_INT32, PF_DEC}, {"cmd", PT_FLAGS16, PF_HEX, semctl_commands}, {"val", PT_INT32, PF_DEC} } }, + /* PPME_SYSCALL_SEMCTL_X */{"semctl", EC_PROCESS, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_PPOLL_E */{"ppoll", EC_WAIT, EF_WAITS, 3, {{"fds", PT_FDLIST, PF_DEC}, {"timeout", PT_RELTIME, PF_DEC}, {"sigmask", PT_SIGSET, PF_DEC} } }, + /* PPME_SYSCALL_PPOLL_X */{"ppoll", EC_WAIT, EF_WAITS, 2, {{"res", PT_ERRNO, PF_DEC}, {"fds", PT_FDLIST, PF_DEC} } }, /* PPME_SYSCALL_MOUNT_E */{"mount", EC_FILE, EF_MODIFIES_STATE, 1, {{"flags", PT_FLAGS32, PF_HEX, mount_flags} } }, /* PPME_SYSCALL_MOUNT_X */{"mount", EC_FILE, 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, EF_MODIFIES_STATE, 1, {{"flags", PT_FLAGS32, PF_HEX, umount_flags} } }, /* PPME_SYSCALL_UMOUNT_X */{"umount", EC_FILE, EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"name", PT_FSPATH, PF_NA} } }, /* PPME_K8S_E */{"k8s", EC_INTERNAL, EF_SKIPPARSERESET | EF_MODIFIES_STATE, 1, {{"json", PT_CHARBUF, PF_NA} } }, /* PPME_K8S_X */{"NA3", EC_SYSTEM, EF_UNUSED, 0}, - /* PPME_SYSCALL_SEMGET_E */{"semget", EC_PROCESS, EF_DROP_SIMPLE_CONS, 3, {{"key", PT_INT32, PF_HEX}, {"nsems", PT_INT32, PF_DEC}, {"semflg", PT_FLAGS32, PF_HEX, semget_flags} } }, - /* PPME_SYSCALL_SEMGET_X */{"semget", EC_PROCESS, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, - /* PPME_SYSCALL_ACCESS_E */{"access", EC_FILE, EF_DROP_SIMPLE_CONS, 1, {{"mode", PT_FLAGS32, PF_HEX, access_flags} } }, - /* PPME_SYSCALL_ACCESS_X */{"access", EC_FILE, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"name", PT_FSPATH, PF_NA} } }, + /* PPME_SYSCALL_SEMGET_E */{"semget", EC_PROCESS, EF_NONE, 3, {{"key", PT_INT32, PF_HEX}, {"nsems", PT_INT32, PF_DEC}, {"semflg", PT_FLAGS32, PF_HEX, semget_flags} } }, + /* PPME_SYSCALL_SEMGET_X */{"semget", EC_PROCESS, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_ACCESS_E */{"access", EC_FILE, EF_NONE, 1, {{"mode", PT_FLAGS32, PF_HEX, access_flags} } }, + /* PPME_SYSCALL_ACCESS_X */{"access", EC_FILE, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"name", PT_FSPATH, PF_NA} } }, /* PPME_SYSCALL_CHROOT_E */{"chroot", EC_PROCESS, EF_MODIFIES_STATE, 0}, /* PPME_SYSCALL_CHROOT_X */{"chroot", EC_PROCESS, EF_MODIFIES_STATE, 2, {{"res", PT_ERRNO, PF_DEC}, {"path", PT_FSPATH, PF_NA} } }, /* PPME_TRACER_E */{"tracer", EC_OTHER, EF_NONE, 3, {{"id", PT_INT64, PF_DEC}, {"tags", PT_CHARBUFARRAY, PF_NA}, {"args", PT_CHARBUF_PAIR_ARRAY, PF_NA} } }, @@ -302,7 +302,7 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_INFRASTRUCTURE_EVENT_X */{"NA4", EC_SYSTEM, EF_UNUSED, 0}, /* PPME_SYSCALL_EXECVE_18_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 1, {{"filename", PT_FSPATH, PF_NA} } }, /* PPME_SYSCALL_EXECVE_18_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE | EF_OLD_VERSION, 17, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, 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}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC} } }, - /* PPME_PAGE_FAULT_E */ {"page_fault", EC_OTHER, EF_SKIPPARSERESET | EF_DROP_SIMPLE_CONS, 3, {{"addr", PT_UINT64, PF_HEX}, {"ip", PT_UINT64, PF_HEX}, {"error", PT_FLAGS32, PF_HEX, pf_flags} } }, + /* PPME_PAGE_FAULT_E */ {"page_fault", EC_OTHER, EF_SKIPPARSERESET, 3, {{"addr", PT_UINT64, PF_HEX}, {"ip", PT_UINT64, PF_HEX}, {"error", PT_FLAGS32, PF_HEX, pf_flags} } }, /* PPME_PAGE_FAULT_X */ {"NA5", EC_OTHER, EF_UNUSED, 0}, /* PPME_SYSCALL_EXECVE_19_E */{"execve", EC_PROCESS, EF_MODIFIES_STATE, 1, {{"filename", PT_FSPATH, PF_NA} } }, /* PPME_SYSCALL_EXECVE_19_X */{"execve", EC_PROCESS, EF_MODIFIES_STATE, 23, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, 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}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC}, {"pgid", PT_PID, PF_DEC}, {"loginuid", PT_INT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, execve_flags}, {"cap_inheritable", PT_UINT64, PF_HEX}, {"cap_permitted", PT_UINT64, PF_HEX}, {"cap_effective", PT_UINT64, PF_HEX} } }, @@ -340,8 +340,8 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_CONTAINER_JSON_2_X */{"container", EC_PROCESS, EF_UNUSED, 0}, /* PPME_SYSCALL_OPENAT2_E */{"openat2", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 5, {{"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } }, /* PPME_SYSCALL_OPENAT2_X */{"openat2", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 6, {{"fd", PT_FD, PF_DEC}, {"dirfd", PT_FD, PF_DEC}, {"name", PT_FSRELPATH, PF_NA, DIRFD_PARAM(1)}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"mode", PT_UINT32, PF_OCT}, {"resolve", PT_FLAGS32, PF_HEX, openat2_flags} } }, - /* PPME_SYSCALL_MPROTECT_E */{"mprotect", EC_MEMORY, EF_DROP_SIMPLE_CONS, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } }, - /* PPME_SYSCALL_MPROTECT_X */{"mprotect", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC} } }, + /* PPME_SYSCALL_MPROTECT_E */{"mprotect", EC_MEMORY, EF_NONE, 3, {{"addr", PT_UINT64, PF_HEX}, {"length", PT_UINT64, PF_DEC}, {"prot", PT_FLAGS32, PF_HEX, prot_flags} } }, + /* PPME_SYSCALL_MPROTECT_X */{"mprotect", EC_MEMORY, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC} } }, /* PPME_SYSCALL_EXECVEAT_E */{"execveat", EC_PROCESS, EF_MODIFIES_STATE, 3, {{"dirfd", PT_FD, PF_DEC}, {"pathname", PT_FSRELPATH, PF_NA, DIRFD_PARAM(0)}, {"flags", PT_FLAGS32, PF_HEX, execveat_flags} } }, /* PPME_SYSCALL_EXECVEAT_X */{"execveat", EC_PROCESS, EF_MODIFIES_STATE, 23, {{"res", PT_ERRNO, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_UINT64, 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}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"env", PT_BYTEBUF, PF_NA}, {"tty", PT_INT32, PF_DEC}, {"pgid", PT_PID, PF_DEC}, {"loginuid", PT_INT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, execve_flags}, {"cap_inheritable", PT_UINT64, PF_HEX}, {"cap_permitted", PT_UINT64, PF_HEX}, {"cap_effective", PT_UINT64, PF_HEX} } }, /* PPME_SYSCALL_COPY_FILE_RANGE_E */{"copy_file_range", EC_FILE, EF_USES_FD | EF_READS_FROM_FD | EF_WRITES_TO_FD, 3, {{"fdin", PT_FD, PF_DEC}, {"offin", PT_UINT64, PF_DEC}, {"len", PT_UINT64, PF_DEC} } }, @@ -350,20 +350,20 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_CLONE3_X */{"clone3", EC_PROCESS, EF_MODIFIES_STATE, 20, {{"res", PT_PID, PF_DEC}, {"exe", PT_CHARBUF, PF_NA}, {"args", PT_BYTEBUF, PF_NA}, {"tid", PT_PID, PF_DEC}, {"pid", PT_PID, PF_DEC}, {"ptid", PT_PID, PF_DEC}, {"cwd", PT_CHARBUF, PF_NA}, {"fdlimit", PT_INT64, 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}, {"comm", PT_CHARBUF, PF_NA}, {"cgroups", PT_BYTEBUF, PF_NA}, {"flags", PT_FLAGS32, PF_HEX, clone_flags}, {"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"vtid", PT_PID, PF_DEC}, {"vpid", PT_PID, PF_DEC} } }, /* PPME_SYSCALL_OPEN_BY_HANDLE_AT_E */{"open_by_handle_at", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, /* PPME_SYSCALL_OPEN_BY_HANDLE_AT_X */{"open_by_handle_at", EC_FILE, EF_CREATES_FD | EF_MODIFIES_STATE, 4, {{"fd", PT_FD, PF_DEC}, {"mountfd", PT_FD, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, file_flags}, {"path", PT_FSPATH, PF_NA} } }, - /* PPME_SYSCALL_IO_URING_SETUP_E */ {"io_uring_setup", EC_IO_OTHER, EF_CREATES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_IO_URING_SETUP_X */ {"io_uring_setup", EC_IO_OTHER, EF_CREATES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 8, {{"res", PT_ERRNO, PF_DEC}, {"entries", PT_UINT32, PF_DEC}, {"sq_entries", PT_UINT32, PF_DEC},{"cq_entries", PT_UINT32, PF_DEC},{"flags", PT_FLAGS32, PF_HEX, io_uring_setup_flags},{"sq_thread_cpu", PT_UINT32, PF_DEC}, {"sq_thread_idle", PT_UINT32, PF_DEC},{"features", PT_FLAGS32, PF_HEX, io_uring_setup_feats}}}, - /* PPME_SYSCALL_IO_URING_ENTER_E */ {"io_uring_enter", EC_IO_OTHER, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_IO_URING_ENTER_X */ {"io_uring_enter", EC_IO_OTHER, EF_USES_FD | EF_WRITES_TO_FD | EF_DROP_SIMPLE_CONS, 6, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"to_submit", PT_UINT32, PF_DEC}, {"min_complete", PT_UINT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, io_uring_enter_flags}, {"sig", PT_SIGSET, PF_DEC}}}, - /* PPME_SYSCALL_IO_URING_REGISTER_E */ {"io_uring_register", EC_IO_OTHER, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_TO_URING_REGISTER_X */ {"io_uring_register", EC_IO_OTHER, EF_USES_FD | EF_MODIFIES_STATE | EF_DROP_SIMPLE_CONS, 5, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC }, {"opcode", PT_ENUMFLAGS16, PF_DEC, io_uring_register_opcodes}, {"arg", PT_UINT64, PF_HEX}, {"nr_args", PT_UINT32, PF_DEC}}}, - /* PPME_SYSCALL_MLOCK_E */ {"mlock", EC_MEMORY, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_MLOCK_X */ {"mlock", EC_MEMORY, EF_DROP_SIMPLE_CONS, 3, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}}}, - /* PPME_SYSCALL_MUNLOCK_E */ {"munlock", EC_MEMORY, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_MUNLOCK_X */ {"munlock", EC_MEMORY, EF_DROP_SIMPLE_CONS, 3, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}}}, - /* PPME_SYSCALL_MLOCKALL_E */ {"mlockall", EC_MEMORY, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_MLOCKALL_X */ {"mlockall", EC_MEMORY, EF_DROP_SIMPLE_CONS, 2, {{"res", PT_ERRNO, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, mlockall_flags}}}, - /* PPME_SYSCALL_MUNLOCKALL_E */ {"munlockall", EC_MEMORY, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_MUNLOCKALL_X */ {"munlockall", EC_MEMORY, EF_DROP_SIMPLE_CONS, 1, {{"res", PT_ERRNO, PF_DEC}}}, + /* PPME_SYSCALL_IO_URING_SETUP_E */ {"io_uring_setup", EC_IO_OTHER, EF_CREATES_FD | EF_MODIFIES_STATE, 0}, + /* PPME_SYSCALL_IO_URING_SETUP_X */ {"io_uring_setup", EC_IO_OTHER, EF_CREATES_FD | EF_MODIFIES_STATE, 8, {{"res", PT_ERRNO, PF_DEC}, {"entries", PT_UINT32, PF_DEC}, {"sq_entries", PT_UINT32, PF_DEC},{"cq_entries", PT_UINT32, PF_DEC},{"flags", PT_FLAGS32, PF_HEX, io_uring_setup_flags},{"sq_thread_cpu", PT_UINT32, PF_DEC}, {"sq_thread_idle", PT_UINT32, PF_DEC},{"features", PT_FLAGS32, PF_HEX, io_uring_setup_feats}}}, + /* PPME_SYSCALL_IO_URING_ENTER_E */ {"io_uring_enter", EC_IO_OTHER, EF_NONE, 0}, + /* PPME_SYSCALL_IO_URING_ENTER_X */ {"io_uring_enter", EC_IO_OTHER, EF_USES_FD | EF_WRITES_TO_FD, 6, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC}, {"to_submit", PT_UINT32, PF_DEC}, {"min_complete", PT_UINT32, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, io_uring_enter_flags}, {"sig", PT_SIGSET, PF_DEC}}}, + /* PPME_SYSCALL_IO_URING_REGISTER_E */ {"io_uring_register", EC_IO_OTHER, EF_NONE, 0}, + /* PPME_SYSCALL_TO_URING_REGISTER_X */ {"io_uring_register", EC_IO_OTHER, EF_USES_FD | EF_MODIFIES_STATE, 5, {{"res", PT_ERRNO, PF_DEC}, {"fd", PT_FD, PF_DEC }, {"opcode", PT_ENUMFLAGS16, PF_DEC, io_uring_register_opcodes}, {"arg", PT_UINT64, PF_HEX}, {"nr_args", PT_UINT32, PF_DEC}}}, + /* PPME_SYSCALL_MLOCK_E */ {"mlock", EC_MEMORY, EF_NONE, 0}, + /* PPME_SYSCALL_MLOCK_X */ {"mlock", EC_MEMORY, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}}}, + /* PPME_SYSCALL_MUNLOCK_E */ {"munlock", EC_MEMORY, EF_NONE, 0}, + /* PPME_SYSCALL_MUNLOCK_X */ {"munlock", EC_MEMORY, EF_NONE, 3, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}}}, + /* PPME_SYSCALL_MLOCKALL_E */ {"mlockall", EC_MEMORY, EF_NONE, 0}, + /* PPME_SYSCALL_MLOCKALL_X */ {"mlockall", EC_MEMORY, EF_NONE, 2, {{"res", PT_ERRNO, PF_DEC}, {"flags", PT_FLAGS32, PF_HEX, mlockall_flags}}}, + /* PPME_SYSCALL_MUNLOCKALL_E */ {"munlockall", EC_MEMORY, EF_NONE, 0}, + /* PPME_SYSCALL_MUNLOCKALL_X */ {"munlockall", EC_MEMORY, EF_NONE, 1, {{"res", PT_ERRNO, PF_DEC}}}, /* PPME_SYSCALL_CAPSET_E */{"capset", EC_PROCESS, EF_MODIFIES_STATE, 0}, /* PPME_SYSCALL_CAPSET_X */{"capset", EC_PROCESS, EF_MODIFIES_STATE, 4, {{"res", PT_ERRNO, PF_DEC}, {"cap_inheritable", PT_UINT64, PF_HEX}, {"cap_permitted", PT_UINT64, PF_HEX}, {"cap_effective", PT_UINT64, PF_HEX} } }, /* PPME_USER_ADDED_E */{"useradded", EC_PROCESS, EF_MODIFIES_STATE, 6, {{"uid", PT_UINT32, PF_DEC}, {"gid", PT_UINT32, PF_DEC}, {"name", PT_CHARBUF, PF_NA}, {"home", PT_CHARBUF, PF_NA}, {"shell", PT_CHARBUF, PF_NA}, {"container_id", PT_CHARBUF, PF_NA} } }, diff --git a/driver/main.c b/driver/main.c index 7936480134..af7766d3c0 100644 --- a/driver/main.c +++ b/driver/main.c @@ -191,7 +191,6 @@ static struct class *g_ppm_class; static unsigned int g_ppm_numdevs; static int g_ppm_major; bool g_tracers_enabled = false; -bool g_simple_mode_enabled = false; static DEFINE_PER_CPU(long, g_n_tracepoint_hit); static const struct file_operations g_ppm_fops = { .open = ppm_open, @@ -791,11 +790,6 @@ static int ppm_release(struct inode *inode, struct file *filp) #endif g_tracepoint_registered = false; - /* - * While we're here, disable simple mode if it's active - */ - g_simple_mode_enabled = false; - /* * Reset tracepoint counter */ @@ -1252,13 +1246,6 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = 0; goto cleanup_ioctl; } - case PPM_IOCTL_SET_SIMPLE_MODE: - { - vpr_info("PPM_IOCTL_SET_SIMPLE_MODE, consumer %p\n", consumer_id); - g_simple_mode_enabled = true; - ret = 0; - goto cleanup_ioctl; - } case PPM_IOCTL_ENABLE_PAGE_FAULTS: { vpr_info("PPM_IOCTL_ENABLE_PAGE_FAULTS\n"); @@ -1936,7 +1923,6 @@ static int record_event_consumer(struct ppm_consumer_t *consumer, ASSERT(ring); ring_info = ring->info; - if (!ring->capture_enabled) { put_cpu(); return res; @@ -2310,15 +2296,6 @@ TRACEPOINT_PROBE(syscall_enter_probe, struct pt_regs *regs, long id) enum syscall_flags drop_flags = cur_g_syscall_table[table_index].flags; enum ppm_event_type type; - /* - * Simple mode event filtering - */ - if (g_simple_mode_enabled) { - if ((drop_flags & UF_SIMPLEDRIVER_KEEP) == 0) { - return; - } - } - #ifdef _HAS_SOCKETCALL if (id == socketcall_syscall) { used = true; @@ -2387,15 +2364,6 @@ TRACEPOINT_PROBE(syscall_exit_probe, struct pt_regs *regs, long ret) enum syscall_flags drop_flags = cur_g_syscall_table[table_index].flags; enum ppm_event_type type; - /* - * Simple mode event filtering - */ - if (g_simple_mode_enabled) { - if ((drop_flags & UF_SIMPLEDRIVER_KEEP) == 0) { - return; - } - } - #ifdef _HAS_SOCKETCALL if (id == socketcall_syscall) { used = true; diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 0f065c9db4..87be72e850 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -1559,7 +1559,7 @@ enum ppm_event_flags { EF_WAITS = (1 << 7), /* This event reads data from an FD. */ EF_SKIPPARSERESET = (1 << 8), /* This event shouldn't pollute the parser lastevent state tracker. */ EF_OLD_VERSION = (1 << 9), /* This event is kept for backward compatibility */ - EF_DROP_SIMPLE_CONS = (1 << 10), /* This event can be skipped by consumers that privilege low overhead to full event capture */ + // EF_DROP_SIMPLE_CONS = (1 << 10), /* This event can be skipped by consumers that privilege low overhead to full event capture */ SUPPORT DROPPED EF_LARGE_PAYLOAD = (1 << 11), /* This event has a large payload, ie: up to UINT32_MAX bytes. DO NOT USE ON syscalls-driven events!!! */ }; @@ -1710,7 +1710,7 @@ struct ppm_evt_hdr { #define PPM_IOCTL_ENABLE_SIGNAL_DELIVER _IO(PPM_IOCTL_MAGIC, 15) #define PPM_IOCTL_GET_PROCLIST _IO(PPM_IOCTL_MAGIC, 16) #define PPM_IOCTL_SET_TRACERS_CAPTURE _IO(PPM_IOCTL_MAGIC, 17) -#define PPM_IOCTL_SET_SIMPLE_MODE _IO(PPM_IOCTL_MAGIC, 18) +// #define PPM_IOCTL_SET_SIMPLE_MODE _IO(PPM_IOCTL_MAGIC, 18) Support dropped #define PPM_IOCTL_ENABLE_PAGE_FAULTS _IO(PPM_IOCTL_MAGIC, 19) #define PPM_IOCTL_GET_N_TRACEPOINT_HIT _IO(PPM_IOCTL_MAGIC, 20) #define PPM_IOCTL_GET_DRIVER_VERSION _IO(PPM_IOCTL_MAGIC, 21) @@ -1793,10 +1793,8 @@ enum syscall_flags { UF_USED = (1 << 0), UF_NEVER_DROP = (1 << 1), UF_ALWAYS_DROP = (1 << 2), - UF_SIMPLEDRIVER_KEEP = (1 << 3), ///< Mark a syscall to be kept in simpledriver mode, see scap_enable_simpledriver_mode() + // UF_SIMPLEDRIVER_KEEP = (1 << 3), ///< Mark a syscall to be kept in simpledriver mode, see scap_enable_simpledriver_mode() -> SUPPORT DROPPED UF_ATOMIC = (1 << 4), ///< The handler should not block (interrupt context) - UF_UNINTERESTING = (1 << 5), ///< Marks a syscall as not interesting. Currently only used by BPF probe to avoid tracing uninteresting syscalls. - ///< Kmod uses a different logic path as we communicate with it through ioctls }; struct syscall_evt_pair { diff --git a/driver/syscall_table.c b/driver/syscall_table.c index dc4390f43f..31d2620f9a 100644 --- a/driver/syscall_table.c +++ b/driver/syscall_table.c @@ -62,17 +62,17 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_creat [__NR_creat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_CREAT_E, PPME_SYSCALL_CREAT_X}, #endif - [__NR_close - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X}, + [__NR_close - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X}, [__NR_brk - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_SYSCALL_BRK_4_E, PPME_SYSCALL_BRK_4_X}, [__NR_read - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_READ_E, PPME_SYSCALL_READ_X}, [__NR_write - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_WRITE_E, PPME_SYSCALL_WRITE_X}, - [__NR_execve - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVE_19_E, PPME_SYSCALL_EXECVE_19_X}, - [__NR_clone - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLONE_20_E, PPME_SYSCALL_CLONE_20_X}, + [__NR_execve - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_EXECVE_19_E, PPME_SYSCALL_EXECVE_19_X}, + [__NR_clone - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CLONE_20_E, PPME_SYSCALL_CLONE_20_X}, #ifdef __NR_fork - [__NR_fork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_FORK_20_E, PPME_SYSCALL_FORK_20_X}, + [__NR_fork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_FORK_20_E, PPME_SYSCALL_FORK_20_X}, #endif #ifdef __NR_vfork - [__NR_vfork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_VFORK_20_E, PPME_SYSCALL_VFORK_20_X}, + [__NR_vfork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_VFORK_20_E, PPME_SYSCALL_VFORK_20_X}, #endif #ifdef __NR_pipe [__NR_pipe - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_PIPE_E, PPME_SYSCALL_PIPE_X}, @@ -105,8 +105,8 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_capset [__NR_capset - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_CAPSET_E, PPME_SYSCALL_CAPSET_X}, #endif - [__NR_chdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CHDIR_E, PPME_SYSCALL_CHDIR_X}, - [__NR_fchdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_FCHDIR_E, PPME_SYSCALL_FCHDIR_X}, + [__NR_chdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CHDIR_E, PPME_SYSCALL_CHDIR_X}, + [__NR_fchdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_FCHDIR_E, PPME_SYSCALL_FCHDIR_X}, #ifdef __NR_mkdir [__NR_mkdir - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MKDIR_2_E, PPME_SYSCALL_MKDIR_2_X}, #endif @@ -129,11 +129,11 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { [__NR_writev - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_WRITEV_E, PPME_SYSCALL_WRITEV_X}, [__NR_preadv - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_PREADV_E, PPME_SYSCALL_PREADV_X}, [__NR_pwritev - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_PWRITEV_E, PPME_SYSCALL_PWRITEV_X}, - [__NR_dup - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_DUP_1_E, PPME_SYSCALL_DUP_1_X}, + [__NR_dup - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_DUP_1_E, PPME_SYSCALL_DUP_1_X}, #ifdef __NR_dup2 - [__NR_dup2 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_DUP2_E, PPME_SYSCALL_DUP2_X}, + [__NR_dup2 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_DUP2_E, PPME_SYSCALL_DUP2_X}, #endif - [__NR_dup3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_DUP3_E, PPME_SYSCALL_DUP3_X}, + [__NR_dup3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_DUP3_E, PPME_SYSCALL_DUP3_X}, #ifdef __NR_signalfd [__NR_signalfd - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_SIGNALFD_E, PPME_SYSCALL_SIGNALFD_X}, #endif @@ -195,19 +195,19 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { #endif #ifdef __NR_socket - [__NR_socket - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_SOCKET_E, PPME_SOCKET_SOCKET_X}, + [__NR_socket - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SOCKET_SOCKET_E, PPME_SOCKET_SOCKET_X}, #endif #ifdef __NR_bind [__NR_bind - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SOCKET_BIND_E, PPME_SOCKET_BIND_X}, #endif #ifdef __NR_connect - [__NR_connect - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_CONNECT_E, PPME_SOCKET_CONNECT_X}, + [__NR_connect - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_CONNECT_E, PPME_SOCKET_CONNECT_X}, #endif #ifdef __NR_listen [__NR_listen - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_LISTEN_E, PPME_SOCKET_LISTEN_X}, #endif #ifdef __NR_accept - [__NR_accept - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_ACCEPT_5_E, PPME_SOCKET_ACCEPT_5_X}, + [__NR_accept - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_ACCEPT_5_E, PPME_SOCKET_ACCEPT_5_X}, #endif #ifdef __NR_getsockname [__NR_getsockname - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_SOCKET_GETSOCKNAME_E, PPME_SOCKET_GETSOCKNAME_X}, @@ -237,7 +237,7 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { [__NR_sendmsg - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_SENDMSG_E, PPME_SOCKET_SENDMSG_X}, #endif #ifdef __NR_accept4 - [__NR_accept4 - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_ACCEPT4_5_E, PPME_SOCKET_ACCEPT4_5_X}, + [__NR_accept4 - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_ACCEPT4_5_E, PPME_SOCKET_ACCEPT4_5_X}, #endif #ifdef __NR_sendmmsg @@ -395,13 +395,13 @@ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { [__NR_openat2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_OPENAT2_E, PPME_SYSCALL_OPENAT2_X}, #endif #ifdef __NR_clone3 - [__NR_clone3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLONE3_E, PPME_SYSCALL_CLONE3_X}, + [__NR_clone3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CLONE3_E, PPME_SYSCALL_CLONE3_X}, #endif #ifdef __NR_mprotect [__NR_mprotect - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MPROTECT_E, PPME_SYSCALL_MPROTECT_X}, #endif #ifdef __NR_execveat - [__NR_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X}, + [__NR_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X}, #endif #ifdef __NR_io_uring_setup [__NR_io_uring_setup - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_IO_URING_SETUP_E, PPME_SYSCALL_IO_URING_SETUP_X}, @@ -1120,14 +1120,14 @@ const enum ppm_syscall_code g_syscall_code_routing_table[SYSCALL_TABLE_SIZE] = { const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { [__NR_ia32_open - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_OPEN_E, PPME_SYSCALL_OPEN_X}, [__NR_ia32_creat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_CREAT_E, PPME_SYSCALL_CREAT_X}, - [__NR_ia32_close - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X}, + [__NR_ia32_close - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X}, [__NR_ia32_brk - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_SYSCALL_BRK_4_E, PPME_SYSCALL_BRK_4_X}, [__NR_ia32_read - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_READ_E, PPME_SYSCALL_READ_X}, [__NR_ia32_write - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_WRITE_E, PPME_SYSCALL_WRITE_X}, - [__NR_ia32_execve - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVE_19_E, PPME_SYSCALL_EXECVE_19_X}, - [__NR_ia32_clone - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLONE_20_E, PPME_SYSCALL_CLONE_20_X}, - [__NR_ia32_fork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_FORK_20_E, PPME_SYSCALL_FORK_20_X}, - [__NR_ia32_vfork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_VFORK_20_E, PPME_SYSCALL_VFORK_20_X}, + [__NR_ia32_execve - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_EXECVE_19_E, PPME_SYSCALL_EXECVE_19_X}, + [__NR_ia32_clone - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CLONE_20_E, PPME_SYSCALL_CLONE_20_X}, + [__NR_ia32_fork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_FORK_20_E, PPME_SYSCALL_FORK_20_X}, + [__NR_ia32_vfork - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_VFORK_20_E, PPME_SYSCALL_VFORK_20_X}, [__NR_ia32_pipe - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_PIPE_E, PPME_SYSCALL_PIPE_X}, [__NR_ia32_pipe2 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_PIPE_E, PPME_SYSCALL_PIPE_X}, [__NR_ia32_eventfd - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_EVENTFD_E, PPME_SYSCALL_EVENTFD_X}, @@ -1147,8 +1147,8 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_ia32_capset [__NR_ia32_capset - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_CAPSET_E, PPME_SYSCALL_CAPSET_X}, #endif - [__NR_ia32_chdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CHDIR_E, PPME_SYSCALL_CHDIR_X}, - [__NR_ia32_fchdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_FCHDIR_E, PPME_SYSCALL_FCHDIR_X}, + [__NR_ia32_chdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CHDIR_E, PPME_SYSCALL_CHDIR_X}, + [__NR_ia32_fchdir - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_FCHDIR_E, PPME_SYSCALL_FCHDIR_X}, [__NR_ia32_mkdir - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MKDIR_2_E, PPME_SYSCALL_MKDIR_2_X}, [__NR_ia32_rmdir - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_RMDIR_2_E, PPME_SYSCALL_RMDIR_2_X}, [__NR_ia32_openat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X}, @@ -1163,9 +1163,9 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { [__NR_ia32_writev - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_WRITEV_E, PPME_SYSCALL_WRITEV_X}, [__NR_ia32_preadv - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_PREADV_E, PPME_SYSCALL_PREADV_X}, [__NR_ia32_pwritev - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_PWRITEV_E, PPME_SYSCALL_PWRITEV_X}, - [__NR_ia32_dup - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_DUP_1_E, PPME_SYSCALL_DUP_1_X}, - [__NR_ia32_dup2 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_DUP2_E, PPME_SYSCALL_DUP2_X}, - [__NR_ia32_dup3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_DUP3_E, PPME_SYSCALL_DUP3_X}, + [__NR_ia32_dup - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_DUP_1_E, PPME_SYSCALL_DUP_1_X}, + [__NR_ia32_dup2 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_DUP2_E, PPME_SYSCALL_DUP2_X}, + [__NR_ia32_dup3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_DUP3_E, PPME_SYSCALL_DUP3_X}, [__NR_ia32_signalfd - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_SIGNALFD_E, PPME_SYSCALL_SIGNALFD_X}, [__NR_ia32_signalfd4 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SYSCALL_SIGNALFD_E, PPME_SYSCALL_SIGNALFD_X}, [__NR_ia32_kill - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_KILL_E, PPME_SYSCALL_KILL_X}, @@ -1208,11 +1208,11 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { [__NR_ia32_pause - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_GENERIC_E, PPME_GENERIC_X}, #ifndef __NR_ia32_socketcall - [__NR_ia32_socket - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_SOCKET_E, PPME_SOCKET_SOCKET_X}, + [__NR_ia32_socket - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_SOCKET_E, PPME_SOCKET_SOCKET_X}, [__NR_ia32_bind - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_BIND_E, PPME_SOCKET_BIND_X}, - [__NR_ia32_connect - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_CONNECT_E, PPME_SOCKET_CONNECT_X}, + [__NR_ia32_connect - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_CONNECT_E, PPME_SOCKET_CONNECT_X}, [__NR_ia32_listen - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_LISTEN_E, PPME_SOCKET_LISTEN_X}, - [__NR_ia32_accept - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_ACCEPT_E, PPME_SOCKET_ACCEPT_X}, + [__NR_ia32_accept - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_ACCEPT_E, PPME_SOCKET_ACCEPT_X}, [__NR_ia32_getsockname - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_SOCKET_GETSOCKNAME_E, PPME_SOCKET_GETSOCKNAME_X}, [__NR_ia32_getpeername - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_SOCKET_GETPEERNAME_E, PPME_SOCKET_GETPEERNAME_X}, [__NR_ia32_socketpair - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP, PPME_SOCKET_SOCKETPAIR_E, PPME_SOCKET_SOCKETPAIR_X}, @@ -1222,7 +1222,7 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { [__NR_ia32_setsockopt - SYSCALL_TABLE_ID0] = {UF_USED | UF_ALWAYS_DROP, PPME_SOCKET_SETSOCKOPT_E, PPME_SOCKET_SETSOCKOPT_X}, [__NR_ia32_getsockopt - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_GETSOCKOPT_E, PPME_SOCKET_GETSOCKOPT_X}, [__NR_ia32_sendmsg - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SOCKET_SENDMSG_E, PPME_SOCKET_SENDMSG_X}, - [__NR_ia32_accept4 - SYSCALL_TABLE_ID0] = {UF_USED | UF_SIMPLEDRIVER_KEEP, PPME_SOCKET_ACCEPT4_E, PPME_SOCKET_ACCEPT4_X}, + [__NR_ia32_accept4 - SYSCALL_TABLE_ID0] = {UF_USED , PPME_SOCKET_ACCEPT4_E, PPME_SOCKET_ACCEPT4_X}, #endif #ifdef __NR_ia32_sendmmsg @@ -1363,13 +1363,13 @@ const struct syscall_evt_pair g_syscall_ia32_table[SYSCALL_TABLE_SIZE] = { [__NR_ia32_openat2 - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_OPENAT2_E, PPME_SYSCALL_OPENAT2_X}, #endif #ifdef __NR_ia32_clone3 - [__NR_ia32_clone3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_CLONE3_E, PPME_SYSCALL_CLONE3_X}, + [__NR_ia32_clone3 - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_CLONE3_E, PPME_SYSCALL_CLONE3_X}, #endif #ifdef __NR_ia32_mprotect [__NR_ia32_mprotect - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_MPROTECT_E, PPME_SYSCALL_MPROTECT_X}, #endif #ifdef __NR_ia32_execveat - [__NR_ia32_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP | UF_SIMPLEDRIVER_KEEP, PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X}, + [__NR_ia32_execveat - SYSCALL_TABLE_ID0] = {UF_USED | UF_NEVER_DROP , PPME_SYSCALL_EXECVEAT_E, PPME_SYSCALL_EXECVEAT_X}, #endif #ifdef __NR_ia32_io_uring_setup [__NR_ia32_io_uring_setup - SYSCALL_TABLE_ID0] = {UF_USED, PPME_SYSCALL_IO_URING_SETUP_E, PPME_SYSCALL_IO_URING_SETUP_X}, diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 9af2f65d05..4632a3394a 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -886,20 +886,30 @@ static int32_t populate_syscall_routing_table_map(struct bpf_engine *handle) static int32_t populate_syscall_table_map(struct bpf_engine *handle) { - static const struct syscall_evt_pair uninterested_pair = { .flags = UF_UNINTERESTING }; int j; for(j = 0; j < SYSCALL_TABLE_SIZE; ++j) { const struct syscall_evt_pair *p = &g_syscall_table[j]; - if (!handle->m_syscalls_of_interest[j]) + if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SYSCALL_TABLE], &j, p, BPF_ANY) != 0) { - p = &uninterested_pair; + snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SYSCALL_TABLE bpf_map_update_elem < 0"); + return SCAP_FAILURE; } + } - if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SYSCALL_TABLE], &j, p, BPF_ANY) != 0) + return bpf_map_freeze(handle->m_bpf_map_fds[SCAP_SYSCALL_TABLE]); +} + +static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle) +{ + int j; + + for(j = 0; j < SYSCALL_TABLE_SIZE; ++j) + { + if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &j, &handle->m_syscalls_of_interest[j], BPF_ANY) != 0) { - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SYSCALL_TABLE bpf_map_update_elem < 0"); + snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_INTERESTING_SYSCALLS_TABLE bpf_map_update_elem < 0"); return SCAP_FAILURE; } } @@ -968,6 +978,7 @@ static int32_t calibrate_socket_file_ops() int32_t scap_bpf_start_capture(struct scap_engine_handle engine) { struct bpf_engine* handle = engine.m_handle; + struct scap_bpf_settings settings; int k = 0; @@ -1451,6 +1462,11 @@ int32_t scap_bpf_load( return SCAP_FAILURE; } + if(populate_interesting_syscalls_map(handle) != SCAP_SUCCESS) + { + return SCAP_FAILURE; + } + if(populate_event_table_map(handle) != SCAP_SUCCESS) { return SCAP_FAILURE; @@ -1621,21 +1637,6 @@ int32_t scap_bpf_get_n_tracepoint_hit(struct scap_engine_handle engine, long* re return SCAP_SUCCESS; } -int32_t scap_bpf_set_simple_mode(struct scap_engine_handle engine) -{ - struct bpf_engine *handle = engine.m_handle; - int j; - for(j = 0; j < SYSCALL_TABLE_SIZE; ++j) - { - const struct syscall_evt_pair *p = &g_syscall_table[j]; - if(!(p->flags & UF_SIMPLEDRIVER_KEEP)) - { - handle->m_syscalls_of_interest[j] = false; - } - } - return populate_syscall_table_map(handle); -} - int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t event_id) { int j; bool quit = false; @@ -1669,7 +1670,9 @@ int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op } } } - return populate_syscall_table_map(handle); + + // Perhaps we could just update a single element here when op != PPM_IOCTL_MASK_ZERO_EVENTS ? + return populate_interesting_syscalls_map(handle); } static int32_t next(struct scap_engine_handle engine, OUT scap_evt** pevent, OUT uint16_t* pcpuid) @@ -1723,12 +1726,6 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set { return scap_bpf_enable_dynamic_snaplen(engine); } - case SCAP_SIMPLEDRIVER_MODE: - if(arg1 == 0) - { - return unsupported_config(engine, "Simpledriver mode cannot be disabled once enabled"); - } - return scap_bpf_set_simple_mode(engine); case SCAP_FULLCAPTURE_PORT_RANGE: return scap_bpf_set_fullcapture_port_range(engine, arg1, arg2); case SCAP_STATSD_PORT: @@ -1763,7 +1760,7 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) engine.m_handle->m_ncpus = num_cpus; - fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, &engine.m_handle->m_syscalls_of_interest); + fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, engine.m_handle->m_syscalls_of_interest); rc = devset_init(&engine.m_handle->m_dev_set, num_cpus, engine.m_handle->m_lasterr); if(rc != SCAP_SUCCESS) diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index e84118fceb..6bd5708ac5 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -108,7 +108,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) { return rc; } - fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, &handle->syscalls_of_interest); + fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, handle->syscalls_of_interest); // // Allocate the device descriptors. @@ -549,18 +549,6 @@ int32_t scap_kmod_disable_dynamic_snaplen(struct scap_engine_handle engine) return SCAP_SUCCESS; } -int32_t scap_kmod_enable_simpledriver_mode(struct scap_engine_handle engine) -{ - if(ioctl(engine.m_handle->m_dev_set.m_devs[0].m_fd, PPM_IOCTL_SET_SIMPLE_MODE)) - { - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, "scap_enable_simpledriver_mode failed"); - ASSERT(false); - return SCAP_FAILURE; - } - - return SCAP_SUCCESS; -} - int32_t scap_kmod_get_n_tracepoint_hit(struct scap_engine_handle engine, long* ret) { int ioctl_ret = 0; @@ -699,12 +687,6 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set { return scap_kmod_enable_dynamic_snaplen(engine); } - case SCAP_SIMPLEDRIVER_MODE: - if(arg1 == 0) - { - return unsupported_config(engine, "Simpledriver mode cannot be disabled once enabled"); - } - return scap_kmod_enable_simpledriver_mode(engine); case SCAP_FULLCAPTURE_PORT_RANGE: return scap_kmod_set_fullcapture_port_range(engine, arg1, arg2); case SCAP_STATSD_PORT: diff --git a/userspace/libscap/engine/udig/scap_udig.c b/userspace/libscap/engine/udig/scap_udig.c index 591317a260..35ce75c5b0 100644 --- a/userspace/libscap/engine/udig/scap_udig.c +++ b/userspace/libscap/engine/udig/scap_udig.c @@ -832,14 +832,6 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set return SCAP_NOT_SUPPORTED; case SCAP_SNAPLEN: return udig_set_snaplen(engine, arg1); - case SCAP_SIMPLEDRIVER_MODE: - if(arg1 == 0) - { - return unsupported_config(engine, "Simpledriver mode cannot be disabled once enabled"); - } - // the original code blindly tries a kmod-only ioctl - // which can only fail. Let's return a better error code instead - return SCAP_NOT_SUPPORTED; case SCAP_EVENTMASK: case SCAP_DYNAMIC_SNAPLEN: case SCAP_STATSD_PORT: diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 0b2a0705f4..ebda6134bf 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -25,7 +25,6 @@ limitations under the License. #define BPF_OPTION "--bpf" #define MODERN_BPF_OPTION "--modern_bpf" #define SCAP_FILE_OPTION "--scap_file" -#define SIMPLE_CONSUMER_OPTION "--simple_consumer" #define NUM_EVENTS_OPTION "--num_events" #define EVENT_TYPE_OPTION "--evt_type" #define VALIDATION_OPTION "--validate_syscalls" @@ -47,7 +46,6 @@ struct scap_savefile_engine_params savefile_params; /* Configuration variables set through CLI. */ uint64_t num_events = UINT64_MAX; /* max number of events to catch. */ -bool simple_consumer = false; /* kernel simple consumer mode. */ int evt_type = -1; /* event type to print. */ /* Generic global variables. */ @@ -334,8 +332,6 @@ void print_sorted_syscalls(char string_vector[SYSCALL_TABLE_SIZE][SYSCALL_NAME_M /* This are the real interesting syscalls that we want to support in the new probe. * - all syscalls associated with events of type `UF_NEVER_DROP`. - * - all syscalls that are not managed through `GENERIC_EVENTS` and don't - * have the `EF_DROP_SIMPLE_CONS` flag. * * Please note: if some syscalls miss, probably, you have an old kernel * that don't define them. Try to use a newer one. @@ -362,10 +358,8 @@ void print_modern_probe_syscalls() continue; } - /* TAKE NEVER: If we use generic events, we can drop the syscall with the simple consumer logic. - * Same thing if the syscall has the `EF_DROP_SIMPLE_CONS`. - */ - if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E || g_syscall_info_table[ppm_syscall_code].flags & EF_DROP_SIMPLE_CONS) + /* TAKE NEVER: If we use generic events, we can drop the syscall with the simple consumer logic.*/ + if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E) { continue; } @@ -384,9 +378,8 @@ void print_modern_probe_syscalls() printf("unexpected error, please check with `%s` option", VALIDATION_OPTION); } -/* Print syscall supported by actual drivers: `KERNEL_MODULE`, `BPF_PROBE`. - * You can also print only simple consumer syscalls by passing the CLI - * option `--simple_consumer`. +/* + * Print syscall supported by actual drivers: `KERNEL_MODULE`, `BPF_PROBE`. */ void print_actual_drivers_syscalls() { @@ -414,11 +407,9 @@ void print_actual_drivers_syscalls() /* Print all supported syscall according to the scap source you have chosen: * - `KERNEL_MODULE` or `BPF_PROBE`, print all syscalls supported by these - * sources. Please note: you can also print only simple consumer syscalls - * by passing the CLI option `--simple_consumer` + * sources * - `MODERN_BPF_PROBE`, print all syscalls that will be supported by - * modern BPF probe. These syscall are a subset of actual simple consumer. - * `--simple_consumer` option will have no effect on this print. + * modern BPF probe. * - `SCAP_FILE` not supported by this function. */ void print_supported_syscalls() @@ -461,7 +452,7 @@ void validate_syscalls() continue; } - if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E || g_syscall_info_table[ppm_syscall_code].flags & EF_DROP_SIMPLE_CONS) + if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E) { continue; } @@ -500,7 +491,6 @@ void print_help() printf("'%s': enable modern BPF probe.\n", MODERN_BPF_OPTION); printf("'%s ': read events from scap file.\n", SCAP_FILE_OPTION); printf("\n------> CONFIGURATIONS OPTIONS\n"); - printf("'%s': enable the simple consumer mode. (default: disabled)\n", SIMPLE_CONSUMER_OPTION); printf("'%s ': number of events to catch before terminating. (default: UINT64_MAX)\n", NUM_EVENTS_OPTION); printf("'%s ': every event of this type will be printed to console. (default: -1, no print)\n", EVENT_TYPE_OPTION); printf("\n------> VALIDATION OPTIONS\n"); @@ -544,7 +534,6 @@ void print_scap_source() void print_configurations() { printf("---------------------- CONFIGURATIONS ----------------------\n"); - printf("* Simple consumer mode: %d (`1` means enabled).\n", simple_consumer); printf("* Print single event type: %d (`-1` means no event to print).\n", evt_type); printf("* Run until '%lu' events are catched.\n", num_events); printf("--------------------------------------------------------------\n\n"); @@ -627,17 +616,6 @@ void parse_CLI_options(int argc, char** argv) /*=============================== CONFIGURATIONS ===========================*/ - if(!strcmp(argv[i], SIMPLE_CONSUMER_OPTION)) - { - oargs.ppm_sc_of_interest.ppm_sc[PPM_SC_UNKNOWN] = 0; - - /* Starting from '1' since we ignore all the unknown syscalls (PPM_SC_UNKNOWN). */ - for(int j = 1; j < PPM_SC_MAX; j++) - { - oargs.ppm_sc_of_interest.ppm_sc[j] = !(g_syscall_info_table[j].flags & EF_DROP_SIMPLE_CONS); - } - simple_consumer = true; - } if(!strcmp(argv[i], NUM_EVENTS_OPTION)) { if(!(i + 1 < argc)) diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index a8ea645cff..a356f52cc8 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1497,22 +1497,6 @@ void scap_fseek(scap_t *handle, uint64_t off) } } -int32_t scap_enable_simpledriver_mode(scap_t* handle) -{ - if(handle->m_vtable) - { - return handle->m_vtable->configure(handle->m_engine, SCAP_SIMPLEDRIVER_MODE, 1, 0); - } - -#if !defined(HAS_CAPTURE) || defined(CYGWING_AGENT) || defined(_WIN32) - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "live capture not supported on %s", PLATFORM_NAME); - return SCAP_FAILURE; -#else - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "setting simpledriver mode not supported on this scap mode"); - return SCAP_FAILURE; -#endif -} - int32_t scap_get_n_tracepoint_hit(scap_t* handle, long* ret) { if(handle->m_vtable) diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 3f231d9d4e..4b91af19a8 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -1096,9 +1096,6 @@ int32_t scap_write_proclist_entry_bufs(scap_t *handle, scap_dumper_t *d, struct const struct iovec *cgroups, int cgroupscnt, const char *root); -// Turn on processing only a subset syscalls. This is only appliable when scap -// is in LIVE mode. -int32_t scap_enable_simpledriver_mode(scap_t* handle); int32_t scap_get_n_tracepoint_hit(scap_t* handle, long* ret); #ifdef CYGWING_AGENT typedef struct wh_t wh_t; diff --git a/userspace/libscap/scap_engine_util.c b/userspace/libscap/scap_engine_util.c index 55b34d7b3b..fef4d648ff 100644 --- a/userspace/libscap/scap_engine_util.c +++ b/userspace/libscap/scap_engine_util.c @@ -26,7 +26,7 @@ limitations under the License. #endif /* `ppm_sc_of_interest` is never `NULL`, we check it before calling this method. */ -void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool (*syscalls_of_interest)[SYSCALL_TABLE_SIZE]) +void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest) { for (int i = 0; i < PPM_SC_MAX; i++) { @@ -36,10 +36,9 @@ void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool // Find the match between the ppm_sc and the syscall_nr if(g_syscall_code_routing_table[syscall_nr] == i) { - // UF_NEVER_DROP syscalls must be always traced - if (ppm_sc_of_interest->ppm_sc[i] || g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) + if (ppm_sc_of_interest->ppm_sc[i]) { - (*syscalls_of_interest)[syscall_nr] = true; + syscalls_of_interest[syscall_nr] = true; } // DO NOT break as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) } diff --git a/userspace/libscap/scap_engine_util.h b/userspace/libscap/scap_engine_util.h index fb736552b7..aa6d27e1e5 100644 --- a/userspace/libscap/scap_engine_util.h +++ b/userspace/libscap/scap_engine_util.h @@ -17,5 +17,5 @@ limitations under the License. #pragma once -void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool (*syscalls_of_interest)[SYSCALL_TABLE_SIZE]); +void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest); int32_t check_api_compatibility(scap_t *handle, char *error); diff --git a/userspace/libscap/scap_vtable.h b/userspace/libscap/scap_vtable.h index 70dff9e31f..3425c67f5a 100644 --- a/userspace/libscap/scap_vtable.h +++ b/userspace/libscap/scap_vtable.h @@ -79,11 +79,6 @@ enum scap_setting { * arg1: enabled? */ SCAP_DYNAMIC_SNAPLEN, - /** - * @brief simple driver mode - * arg1: enabled? - */ - SCAP_SIMPLEDRIVER_MODE, /** * @brief full capture port range * arg1: min port diff --git a/userspace/libscap/syscall_info_table.c b/userspace/libscap/syscall_info_table.c index e702a0a131..1ae1fb59b6 100644 --- a/userspace/libscap/syscall_info_table.c +++ b/userspace/libscap/syscall_info_table.c @@ -26,27 +26,27 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*dummy*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "" }, /*PPM_SC_RESTART_SYSCALL*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "restart_syscall" }, /*PPM_SC_EXIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "exit" }, - /*PPM_SC_READ*/ { EC_IO_READ, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "read" }, - /*PPM_SC_WRITE*/ { EC_IO_WRITE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "write" }, + /*PPM_SC_READ*/ { EC_IO_READ, (enum ppm_event_flags)(EF_NONE), "read" }, + /*PPM_SC_WRITE*/ { EC_IO_WRITE, (enum ppm_event_flags)(EF_NONE), "write" }, /*PPM_SC_OPEN*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "open" }, - /*PPM_SC_CLOSE*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "close" }, + /*PPM_SC_CLOSE*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "close" }, /*PPM_SC_CREAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "creat" }, /*PPM_SC_LINK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "link" }, /*PPM_SC_UNLINK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "unlink" }, /*PPM_SC_CHDIR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "chdir" }, - /*PPM_SC_TIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "time" }, + /*PPM_SC_TIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "time" }, /*PPM_SC_MKNOD*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "mknod" }, /*PPM_SC_CHMOD*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "chmod" }, - /*PPM_SC_STAT*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "stat" }, - /*PPM_SC_LSEEK*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "lseek" }, - /*PPM_SC_GETPID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getpid" }, + /*PPM_SC_STAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "stat" }, + /*PPM_SC_LSEEK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lseek" }, + /*PPM_SC_GETPID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getpid" }, /*PPM_SC_MOUNT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "mount" }, /*PPM_SC_PTRACE*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "ptrace" }, - /*PPM_SC_ALARM*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "alarm" }, - /*PPM_SC_FSTAT*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fstat" }, - /*PPM_SC_PAUSE*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "pause" }, /* WAIT UNTIL A SIGNAL ARRIVES */ + /*PPM_SC_ALARM*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "alarm" }, + /*PPM_SC_FSTAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fstat" }, + /*PPM_SC_PAUSE*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "pause" }, /* WAIT UNTIL A SIGNAL ARRIVES */ /*PPM_SC_UTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "utime" }, - /*PPM_SC_ACCESS*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "access" }, /* checks whether the calling process can access the file pathname */ + /*PPM_SC_ACCESS*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "access" }, /* checks whether the calling process can access the file pathname */ /*PPM_SC_SYNC*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "sync" }, /* causes all buffered modifications to file metadata and data to be written to the underlying file systems. */ /*PPM_SC_KILL*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "kill" }, /*PPM_SC_RENAME*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "rename" }, @@ -54,169 +54,169 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*PPM_SC_RMDIR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "rmdir" }, /*PPM_SC_DUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "dup" }, /*PPM_SC_PIPE*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "pipe" }, - /*PPM_SC_TIMES*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "times" }, - /*PPM_SC_BRK*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "brk" }, + /*PPM_SC_TIMES*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "times" }, + /*PPM_SC_BRK*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "brk" }, /*PPM_SC_ACCT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "acct" }, /*PPM_SC_IOCTL*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "ioctl" }, - /*PPM_SC_FCNTL*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fcntl" }, + /*PPM_SC_FCNTL*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "fcntl" }, /*PPM_SC_SETPGID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "setpgid" }, - /*PPM_SC_UMASK*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "umask" }, /* sets the calling process's file mode creation mask */ + /*PPM_SC_UMASK*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "umask" }, /* sets the calling process's file mode creation mask */ /*PPM_SC_CHROOT*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "chroot" }, /* changes the root directory of the calling process to that specified in path. This directory will be used for path names beginning with /. The root directory is inherited by all children of the calling process. */ - /*PPM_SC_USTAT*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "ustat" }, /* returns information about a mounted file system. */ + /*PPM_SC_USTAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "ustat" }, /* returns information about a mounted file system. */ /*PPM_SC_DUP2*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "dup2" }, - /*PPM_SC_GETPPID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getppid" }, - /*PPM_SC_GETPGRP*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getpgrp" }, + /*PPM_SC_GETPPID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getppid" }, + /*PPM_SC_GETPGRP*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getpgrp" }, /*PPM_SC_SETSID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "setsid" }, /* creates a session and sets the process group ID */ /*PPM_SC_SETHOSTNAME*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "sethostname" }, - /*PPM_SC_SETRLIMIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "setrlimit" }, /* get/set resource (CPU, FDs, memory...) limits */ - /*PPM_SC_GETRUSAGE*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getrusage" }, /* returns resource usage measures for who */ - /*PPM_SC_GETTIMEOFDAY*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "gettimeofday" }, - /*PPM_SC_SETTIMEOFDAY*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "settimeofday" }, + /*PPM_SC_SETRLIMIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "setrlimit" }, /* get/set resource (CPU, FDs, memory...) limits */ + /*PPM_SC_GETRUSAGE*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getrusage" }, /* returns resource usage measures for who */ + /*PPM_SC_GETTIMEOFDAY*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "gettimeofday" }, + /*PPM_SC_SETTIMEOFDAY*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "settimeofday" }, /*PPM_SC_SYMLINK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "symlink" }, - /*PPM_SC_LSTAT*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "lstat" }, + /*PPM_SC_LSTAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lstat" }, /*PPM_SC_READLINK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "readlink" }, /*PPM_SC_USELIB*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "uselib" }, /* load shared library */ /*PPM_SC_SWAPON*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "swapon" }, /* start/stop swapping to file/device */ /*PPM_SC_REBOOT*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "reboot" }, - /*PPM_SC_MMAP*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mmap" }, - /*PPM_SC_MUNMAP*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "munmap" }, + /*PPM_SC_MMAP*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "mmap" }, + /*PPM_SC_MUNMAP*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "munmap" }, /*PPM_SC_TRUNCATE*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "truncate" }, /* truncate a file to a specified length */ /*PPM_SC_FTRUNCATE*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "ftruncate" }, /* truncate a file to a specified length */ /*PPM_SC_FCHMOD*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fchmod" }, - /*PPM_SC_GETPRIORITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getpriority" }, /* get/set program scheduling priority */ + /*PPM_SC_GETPRIORITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getpriority" }, /* get/set program scheduling priority */ /*PPM_SC_SETPRIORITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "setpriority" }, /* get/set program scheduling priority */ - /*PPM_SC_STATFS*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "statfs" }, /* returns information about a mounted file system */ - /*PPM_SC_FSTATFS*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fstatfs" }, /* returns information about a mounted file system */ + /*PPM_SC_STATFS*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "statfs" }, /* returns information about a mounted file system */ + /*PPM_SC_FSTATFS*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fstatfs" }, /* returns information about a mounted file system */ /*PPM_SC_SYSLOG*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "syslog" }, /* read and/or clear kernel message ring buffer; set console_loglevel */ - /*PPM_SC_SETITIMER*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "setitimer" }, - /*PPM_SC_GETITIMER*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getitimer" }, - /*PPM_SC_UNAME*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "uname" }, /* get name and information about current kernel */ + /*PPM_SC_SETITIMER*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "setitimer" }, + /*PPM_SC_GETITIMER*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "getitimer" }, + /*PPM_SC_UNAME*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "uname" }, /* get name and information about current kernel */ /*PPM_SC_VHANGUP*/ { EC_OTHER , (enum ppm_event_flags)(EF_NONE), "vhangup" }, /* simulates a hangup on the current terminal. This call arranges for other users to have a "clean" terminal at login time. */ - /*PPM_SC_WAIT4*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "wait4" }, /* OBSOLETE */ + /*PPM_SC_WAIT4*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "wait4" }, /* OBSOLETE */ /*PPM_SC_SWAPOFF*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "swapoff" }, /* start/stop swapping to file/device */ /*PPM_SC_SYSINFO*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "sysinfo" }, /* returns information on overall system statistics */ - /*PPM_SC_FSYNC*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fsync" }, /* sync file content */ + /*PPM_SC_FSYNC*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "fsync" }, /* sync file content */ /*PPM_SC_SETDOMAINNAME*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "setdomainname" }, /*PPM_SC_ADJTIMEX*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "adjtimex" }, /* tune kernel clock */ - /*PPM_SC_MPROTECT*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mprotect" }, /* set protection on a region of memory */ + /*PPM_SC_MPROTECT*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "mprotect" }, /* set protection on a region of memory */ /*PPM_SC_INIT_MODULE*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "init_module" }, /* load a kernel module */ /*PPM_SC_DELETE_MODULE*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "delete_module" }, /*PPM_SC_QUOTACTL*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "quotactl" }, - /*PPM_SC_GETPGID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getpgid" }, + /*PPM_SC_GETPGID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getpgid" }, /*PPM_SC_FCHDIR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fchdir" }, /*PPM_SC_SYSFS*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "sysfs" }, /* get file system type information */ /*PPM_SC_PERSONALITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "personality" }, /* set the process execution domain */ - /*PPM_SC_GETDENTS*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getdents" }, /* get directory entries */ - /*PPM_SC_SELECT*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "select" }, + /*PPM_SC_GETDENTS*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "getdents" }, /* get directory entries */ + /*PPM_SC_SELECT*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "select" }, /*PPM_SC_FLOCK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "flock" }, /* apply or remove an advisory lock on an open file */ /*PPM_SC_MSYNC*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "msync" }, /* synchronize a file with a memory map */ - /*PPM_SC_READV*/ { EC_IO_READ, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "readv" }, - /*PPM_SC_WRITEV*/ { EC_IO_WRITE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "writev" }, - /*PPM_SC_GETSID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getsid" }, /* returns the session ID of the calling process */ - /*PPM_SC_FDATASYNC*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fdatasync" }, /* synchronize a file's in-core state with storage device */ - /*PPM_SC_MLOCK*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mlock" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ - /*PPM_SC_MUNLOCK*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "munlock" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ - /*PPM_SC_MLOCKALL*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mlockall" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ - /*PPM_SC_MUNLOCKALL*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "munlockall" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ + /*PPM_SC_READV*/ { EC_IO_READ, (enum ppm_event_flags)(EF_NONE), "readv" }, + /*PPM_SC_WRITEV*/ { EC_IO_WRITE, (enum ppm_event_flags)(EF_NONE), "writev" }, + /*PPM_SC_GETSID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getsid" }, /* returns the session ID of the calling process */ + /*PPM_SC_FDATASYNC*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "fdatasync" }, /* synchronize a file's in-core state with storage device */ + /*PPM_SC_MLOCK*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "mlock" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ + /*PPM_SC_MUNLOCK*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "munlock" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ + /*PPM_SC_MLOCKALL*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "mlockall" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ + /*PPM_SC_MUNLOCKALL*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "munlockall" }, /* mlock() and mlockall() respectively lock part or all of the calling process's virtual address space into RAM */ /*PPM_SC_SCHED_SETPARAM*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_setparam" }, - /*PPM_SC_SCHED_GETPARAM*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sched_getparam" }, + /*PPM_SC_SCHED_GETPARAM*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_getparam" }, /*PPM_SC_SCHED_SETSCHEDULER*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_setscheduler" }, - /*PPM_SC_SCHED_GETSCHEDULER*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sched_getscheduler" }, - /*PPM_SC_SCHED_YIELD*/ { EC_SLEEP, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sched_yield" }, - /*PPM_SC_SCHED_GET_PRIORITY_MAX*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sched_get_priority_max" }, - /*PPM_SC_SCHED_GET_PRIORITY_MIN*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sched_get_priority_min" }, + /*PPM_SC_SCHED_GETSCHEDULER*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_getscheduler" }, + /*PPM_SC_SCHED_YIELD*/ { EC_SLEEP, (enum ppm_event_flags)(EF_NONE), "sched_yield" }, + /*PPM_SC_SCHED_GET_PRIORITY_MAX*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_get_priority_max" }, + /*PPM_SC_SCHED_GET_PRIORITY_MIN*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_get_priority_min" }, /*PPM_SC_SCHED_RR_GET_INTERVAL*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_rr_get_interval" }, - /*PPM_SC_NANOSLEEP*/ { EC_SLEEP, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "nanosleep" }, - /*PPM_SC_MREMAP*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mremap" }, - /*PPM_SC_POLL*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "poll" }, + /*PPM_SC_NANOSLEEP*/ { EC_SLEEP, (enum ppm_event_flags)(EF_NONE), "nanosleep" }, + /*PPM_SC_MREMAP*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "mremap" }, + /*PPM_SC_POLL*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "poll" }, /*PPM_SC_PRCTL*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "prctl" }, /* operations on a process */ - /*PPM_SC_RT_SIGACTION*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "rt_sigaction" }, - /*PPM_SC_RT_SIGPROCMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "rt_sigprocmask" }, - /*PPM_SC_RT_SIGPENDING*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "rt_sigpending" }, - /*PPM_SC_RT_SIGTIMEDWAIT*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "rt_sigtimedwait" }, + /*PPM_SC_RT_SIGACTION*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "rt_sigaction" }, + /*PPM_SC_RT_SIGPROCMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "rt_sigprocmask" }, + /*PPM_SC_RT_SIGPENDING*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "rt_sigpending" }, + /*PPM_SC_RT_SIGTIMEDWAIT*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "rt_sigtimedwait" }, /*PPM_SC_RT_SIGQUEUEINFO*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "rt_sigqueueinfo" }, - /*PPM_SC_RT_SIGSUSPEND*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "rt_sigsuspend" }, - /*PPM_SC_GETCWD*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getcwd" }, - /*PPM_SC_CAPGET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "capget" }, /* set/get capabilities of thread(s) */ + /*PPM_SC_RT_SIGSUSPEND*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "rt_sigsuspend" }, + /*PPM_SC_GETCWD*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "getcwd" }, + /*PPM_SC_CAPGET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "capget" }, /* set/get capabilities of thread(s) */ /*PPM_SC_CAPSET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "capset" }, /* set/get capabilities of thread(s) */ - /*PPM_SC_SENDFILE*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sendfile" }, /* transfer data between file descriptors */ - /*PPM_SC_GETRLIMIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getrlimit" }, + /*PPM_SC_SENDFILE*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "sendfile" }, /* transfer data between file descriptors */ + /*PPM_SC_GETRLIMIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getrlimit" }, /*PPM_SC_LCHOWN*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lchown" }, - /*PPM_SC_GETUID*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getuid" }, - /*PPM_SC_GETGID*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getgid" }, - /*PPM_SC_GETEUID*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "geteuid" }, - /*PPM_SC_GETEGID*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getegid" }, + /*PPM_SC_GETUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "getuid" }, + /*PPM_SC_GETGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "getgid" }, + /*PPM_SC_GETEUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "geteuid" }, + /*PPM_SC_GETEGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "getegid" }, /*PPM_SC_SETREUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setreuid" }, /*PPM_SC_SETREGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setregid" }, - /*PPM_SC_GETGROUPS*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getgroups" }, /* returns the supplementary group IDs of the calling process */ + /*PPM_SC_GETGROUPS*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "getgroups" }, /* returns the supplementary group IDs of the calling process */ /*PPM_SC_SETGROUPS*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setgroups" }, /* returns the supplementary group IDs of the calling process */ /*PPM_SC_FCHOWN*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fchown" }, /*PPM_SC_SETRESUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setresuid" }, - /*PPM_SC_GETRESUID*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getresuid" }, + /*PPM_SC_GETRESUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "getresuid" }, /*PPM_SC_SETRESGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setresgid" }, - /*PPM_SC_GETRESGID*/ { EC_USER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getresgid" }, + /*PPM_SC_GETRESGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "getresgid" }, /*PPM_SC_CHOWN*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "chown" }, /*PPM_SC_SETUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setuid" }, /*PPM_SC_SETGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setgid" }, /*PPM_SC_SETFSUID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setfsuid" }, /*PPM_SC_SETFSGID*/ { EC_USER, (enum ppm_event_flags)(EF_NONE), "setfsgid" }, /*PPM_SC_PIVOT_ROOT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "pivot_root" }, - /*PPM_SC_MINCORE*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mincore" }, /* determine whether pages are resident in memory */ - /*PPM_SC_MADVISE*/ { EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "madvise" }, /* give advice about use of memory */ - /*PPM_SC_GETTID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "gettid" }, /* returns the caller's thread ID (TID) */ + /*PPM_SC_MINCORE*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "mincore" }, /* determine whether pages are resident in memory */ + /*PPM_SC_MADVISE*/ { EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "madvise" }, /* give advice about use of memory */ + /*PPM_SC_GETTID*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "gettid" }, /* returns the caller's thread ID (TID) */ /*PPM_SC_SETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "setxattr" }, /* set inode attribute */ /*PPM_SC_LSETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lsetxattr" }, /*PPM_SC_FSETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fsetxattr" }, - /*PPM_SC_GETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getxattr" }, - /*PPM_SC_LGETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "lgetxattr" }, - /*PPM_SC_FGETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fgetxattr" }, - /*PPM_SC_LISTXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "listxattr" }, - /*PPM_SC_LLISTXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "llistxattr" }, - /*PPM_SC_FLISTXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "flistxattr" }, + /*PPM_SC_GETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "getxattr" }, + /*PPM_SC_LGETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lgetxattr" }, + /*PPM_SC_FGETXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fgetxattr" }, + /*PPM_SC_LISTXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "listxattr" }, + /*PPM_SC_LLISTXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "llistxattr" }, + /*PPM_SC_FLISTXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "flistxattr" }, /*PPM_SC_REMOVEXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "removexattr" }, /*PPM_SC_LREMOVEXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lremovexattr" }, /*PPM_SC_FREMOVEXATTR*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fremovexattr" }, /*PPM_SC_TKILL*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "tkill" }, /* send a signal to a thread */ - /*PPM_SC_FUTEX*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "futex" }, + /*PPM_SC_FUTEX*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "futex" }, /*PPM_SC_SCHED_SETAFFINITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_setaffinity" }, - /*PPM_SC_SCHED_GETAFFINITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sched_getaffinity" }, + /*PPM_SC_SCHED_GETAFFINITY*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "sched_getaffinity" }, /*PPM_SC_SET_THREAD_AREA*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "set_thread_area" }, - /*PPM_SC_GET_THREAD_AREA*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "get_thread_area" }, - /*PPM_SC_IO_SETUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_setup" }, /* create an asynchronous I/O context (for libaio) */ - /*PPM_SC_IO_DESTROY*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_destroy" }, - /*PPM_SC_IO_GETEVENTS*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_getevents" }, - /*PPM_SC_IO_SUBMIT*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_submit" }, - /*PPM_SC_IO_CANCEL*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_cancel" }, - /*PPM_SC_EXIT_GROUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "exit_group" }, - /*PPM_SC_EPOLL_CREATE*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "epoll_create" }, - /*PPM_SC_EPOLL_CTL*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "epoll_ctl" }, - /*PPM_SC_EPOLL_WAIT*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "epoll_wait" }, - /*PPM_SC_REMAP_FILE_PAGES*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "remap_file_pages" }, /* create a nonlinear file mapping */ + /*PPM_SC_GET_THREAD_AREA*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "get_thread_area" }, + /*PPM_SC_IO_SETUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_setup" }, /* create an asynchronous I/O context (for libaio) */ + /*PPM_SC_IO_DESTROY*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_destroy" }, + /*PPM_SC_IO_GETEVENTS*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_getevents" }, + /*PPM_SC_IO_SUBMIT*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_submit" }, + /*PPM_SC_IO_CANCEL*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_cancel" }, + /*PPM_SC_EXIT_GROUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "exit_group" }, + /*PPM_SC_EPOLL_CREATE*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "epoll_create" }, + /*PPM_SC_EPOLL_CTL*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "epoll_ctl" }, + /*PPM_SC_EPOLL_WAIT*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "epoll_wait" }, + /*PPM_SC_REMAP_FILE_PAGES*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "remap_file_pages" }, /* create a nonlinear file mapping */ /*PPM_SC_SET_TID_ADDRESS*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "set_tid_address" }, /* set pointer to thread ID */ - /*PPM_SC_TIMER_CREATE*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timer_create" }, - /*PPM_SC_TIMER_SETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timer_settime" }, - /*PPM_SC_TIMER_GETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timer_gettime" }, - /*PPM_SC_TIMER_GETOVERRUN*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timer_getoverrun" }, - /*PPM_SC_TIMER_DELETE*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timer_delete" }, - /*PPM_SC_CLOCK_SETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "clock_settime" }, - /*PPM_SC_CLOCK_GETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "clock_gettime" }, - /*PPM_SC_CLOCK_GETRES*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "clock_getres" }, - /*PPM_SC_CLOCK_NANOSLEEP*/ { EC_SLEEP, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "clock_nanosleep" }, + /*PPM_SC_TIMER_CREATE*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timer_create" }, + /*PPM_SC_TIMER_SETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timer_settime" }, + /*PPM_SC_TIMER_GETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timer_gettime" }, + /*PPM_SC_TIMER_GETOVERRUN*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timer_getoverrun" }, + /*PPM_SC_TIMER_DELETE*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timer_delete" }, + /*PPM_SC_CLOCK_SETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "clock_settime" }, + /*PPM_SC_CLOCK_GETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "clock_gettime" }, + /*PPM_SC_CLOCK_GETRES*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "clock_getres" }, + /*PPM_SC_CLOCK_NANOSLEEP*/ { EC_SLEEP, (enum ppm_event_flags)(EF_NONE), "clock_nanosleep" }, /*PPM_SC_TGKILL*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "tgkill" }, /*PPM_SC_UTIMES*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "utimes" }, /* change file last access and modification times */ /*PPM_SC_MQ_OPEN*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "mq_open" }, /* Message queues. See http://linux.die.net/man/7/mq_overview. */ /*PPM_SC_MQ_UNLINK*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "mq_unlink" }, - /*PPM_SC_MQ_TIMEDSEND*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mq_timedsend" }, - /*PPM_SC_MQ_TIMEDRECEIVE*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mq_timedreceive" }, - /*PPM_SC_MQ_NOTIFY*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mq_notify" }, - /*PPM_SC_MQ_GETSETATTR*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mq_getsetattr" }, + /*PPM_SC_MQ_TIMEDSEND*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "mq_timedsend" }, + /*PPM_SC_MQ_TIMEDRECEIVE*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "mq_timedreceive" }, + /*PPM_SC_MQ_NOTIFY*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "mq_notify" }, + /*PPM_SC_MQ_GETSETATTR*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "mq_getsetattr" }, /*PPM_SC_KEXEC_LOAD*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "kexec_load" }, /* load a new kernel for later execution */ - /*PPM_SC_WAITID*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "waitid" }, + /*PPM_SC_WAITID*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "waitid" }, /*PPM_SC_ADD_KEY*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "add_key" }, /* add a key to the kernel's key management facility */ /*PPM_SC_REQUEST_KEY*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "request_key" }, /*PPM_SC_KEYCTL*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "keyctl" }, - /*PPM_SC_IOPRIO_SET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "ioprio_set" }, /* get/set I/O scheduling class and priority */ - /*PPM_SC_IOPRIO_GET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "ioprio_get" }, /* get/set I/O scheduling class and priority */ + /*PPM_SC_IOPRIO_SET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "ioprio_set" }, /* get/set I/O scheduling class and priority */ + /*PPM_SC_IOPRIO_GET*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "ioprio_get" }, /* get/set I/O scheduling class and priority */ /*PPM_SC_INOTIFY_INIT*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "inotify_init" }, /* initialize an inotify event queue instance. See http://en.wikipedia.org/wiki/Inotify. */ /*PPM_SC_INOTIFY_ADD_WATCH*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "inotify_add_watch" }, /*PPM_SC_INOTIFY_RM_WATCH*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "inotify_rm_watch" }, @@ -232,30 +232,30 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*PPM_SC_READLINKAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "readlinkat" }, /*PPM_SC_FCHMODAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fchmodat" }, /*PPM_SC_FACCESSAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "faccessat" }, - /*PPM_SC_PSELECT6*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "pselect6" }, - /*PPM_SC_PPOLL*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "ppoll" }, + /*PPM_SC_PSELECT6*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "pselect6" }, + /*PPM_SC_PPOLL*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "ppoll" }, /*PPM_SC_UNSHARE*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "unshare" }, /* disassociate parts of the process execution context */ /*PPM_SC_SET_ROBUST_LIST*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "set_robust_list" }, /* get/set list of robust futexes */ - /*PPM_SC_GET_ROBUST_LIST*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "get_robust_list" }, /* get/set list of robust futexes */ - /*PPM_SC_SPLICE*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "splice" }, /* transfers up to len bytes of data from the file descriptor fd_in to the file descriptor fd_out, where one of the descriptors must refer to a pipe. */ - /*PPM_SC_TEE*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "tee" }, /* tee() duplicates up to len bytes of data from the pipe referred to by the file descriptor fd_in to the pipe referred to by the file descriptor fd_out. It does not consume the data that is duplicated from fd_in. */ - /*PPM_SC_VMSPLICE*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "vmsplice" }, /* splice user pages into a pipe */ - /*PPM_SC_GETCPU*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getcpu" }, /* determine CPU and NUMA node on which the calling thread is running */ - /*PPM_SC_EPOLL_PWAIT*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "epoll_pwait" }, + /*PPM_SC_GET_ROBUST_LIST*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "get_robust_list" }, /* get/set list of robust futexes */ + /*PPM_SC_SPLICE*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "splice" }, /* transfers up to len bytes of data from the file descriptor fd_in to the file descriptor fd_out, where one of the descriptors must refer to a pipe. */ + /*PPM_SC_TEE*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "tee" }, /* tee() duplicates up to len bytes of data from the pipe referred to by the file descriptor fd_in to the pipe referred to by the file descriptor fd_out. It does not consume the data that is duplicated from fd_in. */ + /*PPM_SC_VMSPLICE*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "vmsplice" }, /* splice user pages into a pipe */ + /*PPM_SC_GETCPU*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "getcpu" }, /* determine CPU and NUMA node on which the calling thread is running */ + /*PPM_SC_EPOLL_PWAIT*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "epoll_pwait" }, /*PPM_SC_UTIMENSAT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "utimensat" }, /* change file timestamps with nanosecond precision */ - /*PPM_SC_SIGNALFD*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "signalfd" }, /* create a pollable file descriptor for accepting signals */ - /*PPM_SC_TIMERFD_CREATE*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timerfd_create" }, /* // create and operate on a timer that delivers timer expiration notifications via a file descriptor */ - /*PPM_SC_EVENTFD*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "eventfd" }, /* create a file descriptor for event notification */ - /*PPM_SC_TIMERFD_SETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timerfd_settime" }, /* create and operate on a timer that delivers timer expiration notifications via a file descriptor */ - /*PPM_SC_TIMERFD_GETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "timerfd_gettime" }, /* create and operate on a timer that delivers timer expiration notifications via a file descriptor */ - /*PPM_SC_SIGNALFD4*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "signalfd4" }, /* create a pollable file descriptor for accepting signals */ - /*PPM_SC_EVENTFD2*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "eventfd2" }, /* create a file descriptor for event notification */ - /*PPM_SC_EPOLL_CREATE1*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "epoll_create1" }, /* variant of epoll_create */ + /*PPM_SC_SIGNALFD*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "signalfd" }, /* create a pollable file descriptor for accepting signals */ + /*PPM_SC_TIMERFD_CREATE*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timerfd_create" }, /* // create and operate on a timer that delivers timer expiration notifications via a file descriptor */ + /*PPM_SC_EVENTFD*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "eventfd" }, /* create a file descriptor for event notification */ + /*PPM_SC_TIMERFD_SETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timerfd_settime" }, /* create and operate on a timer that delivers timer expiration notifications via a file descriptor */ + /*PPM_SC_TIMERFD_GETTIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "timerfd_gettime" }, /* create and operate on a timer that delivers timer expiration notifications via a file descriptor */ + /*PPM_SC_SIGNALFD4*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "signalfd4" }, /* create a pollable file descriptor for accepting signals */ + /*PPM_SC_EVENTFD2*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "eventfd2" }, /* create a file descriptor for event notification */ + /*PPM_SC_EPOLL_CREATE1*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "epoll_create1" }, /* variant of epoll_create */ /*PPM_SC_DUP3*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "dup3" }, /*PPM_SC_PIPE2*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "pipe2" }, /*PPM_SC_INOTIFY_INIT1*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "inotify_init1" }, - /*PPM_SC_PREADV*/ { EC_IO_READ, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "preadv" }, - /*PPM_SC_PWRITEV*/ { EC_IO_WRITE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "pwritev" }, + /*PPM_SC_PREADV*/ { EC_IO_READ, (enum ppm_event_flags)(EF_NONE), "preadv" }, + /*PPM_SC_PWRITEV*/ { EC_IO_WRITE, (enum ppm_event_flags)(EF_NONE), "pwritev" }, /*PPM_SC_RT_TGSIGQUEUEINFO*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "rt_tgsigqueueinfo" }, /*PPM_SC_PERF_EVENT_OPEN*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "perf_event_open" }, /*PPM_SC_FANOTIFY_INIT*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "fanotify_init" }, @@ -263,7 +263,7 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*PPM_SC_CLOCK_ADJTIME*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "clock_adjtime" }, /*PPM_SC_SYNCFS*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "syncfs" }, /*PPM_SC_SETNS*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "setns" }, /* reassociate thread with a namespace */ - /*PPM_SC_GETDENTS64*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getdents64" }, + /*PPM_SC_GETDENTS64*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "getdents64" }, /* */ /* Non-multiplexed socket family */ /* */ @@ -272,77 +272,77 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*PPM_SC_CONNECT*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "connect" }, /*PPM_SC_LISTEN*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "listen" }, /*PPM_SC_ACCEPT*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "accept" }, - /*PPM_SC_GETSOCKNAME*/ { EC_NET, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getsockname" }, - /*PPM_SC_GETPEERNAME*/ { EC_NET, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getpeername" }, + /*PPM_SC_GETSOCKNAME*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "getsockname" }, + /*PPM_SC_GETPEERNAME*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "getpeername" }, /*PPM_SC_SOCKETPAIR*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "socketpair" }, /*PPM_SC_SENDTO*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "sendto" }, /*PPM_SC_RECVFROM*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "recvfrom" }, - /*PPM_SC_SHUTDOWN*/ { EC_NET, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "shutdown" }, + /*PPM_SC_SHUTDOWN*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "shutdown" }, /*PPM_SC_SETSOCKOPT*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "setsockopt" }, - /*PPM_SC_GETSOCKOPT*/ { EC_NET, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getsockopt" }, + /*PPM_SC_GETSOCKOPT*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "getsockopt" }, /*PPM_SC_SENDMSG*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "sendmsg" }, - /*PPM_SC_SENDMMSG*/ { EC_NET, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sendmmsg" }, + /*PPM_SC_SENDMMSG*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "sendmmsg" }, /*PPM_SC_RECVMSG*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "recvmsg" }, - /*PPM_SC_RECVMMSG*/ { EC_NET, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "recvmmsg" }, + /*PPM_SC_RECVMMSG*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "recvmmsg" }, /*PPM_SC_ACCEPT4*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "accept4" }, /* * Non-multiplexed IPC family */ - /*PPM_SC_SEMOP*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "semop" }, - /*PPM_SC_SEMGET*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "semget" }, - /*PPM_SC_SEMCTL*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "semctl" }, - /*PPM_SC_MSGSND*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "msgsnd" }, - /*PPM_SC_MSGRCV*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "msgrcv" }, - /*PPM_SC_MSGGET*/ { EC_IPC, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "msgget" }, + /*PPM_SC_SEMOP*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "semop" }, + /*PPM_SC_SEMGET*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "semget" }, + /*PPM_SC_SEMCTL*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "semctl" }, + /*PPM_SC_MSGSND*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "msgsnd" }, + /*PPM_SC_MSGRCV*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "msgrcv" }, + /*PPM_SC_MSGGET*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "msgget" }, /*PPM_SC_MSGCTL*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "msgctl" }, /*PPM_SC_SHMDT*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "shmdt" }, /*PPM_SC_SHMGET*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "shmget" }, /*PPM_SC_SHMCTL*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "shmctl" }, - /*PPM_SC_STATFS64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "statfs64" }, - /*PPM_SC_FSTATFS64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fstatfs64" }, - /*PPM_SC_FSTATAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fstatat64" }, - /*PPM_SC_SENDFILE64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sendfile64" }, - /*PPM_SC_UGETRLIMIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "ugetrlimit" }, + /*PPM_SC_STATFS64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "statfs64" }, + /*PPM_SC_FSTATFS64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fstatfs64" }, + /*PPM_SC_FSTATAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fstatat64" }, + /*PPM_SC_SENDFILE64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "sendfile64" }, + /*PPM_SC_UGETRLIMIT*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "ugetrlimit" }, /*PPM_SC_BDFLUSH*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "bdflush" }, /* deprecated */ - /*PPM_SC_SIGPROCMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sigprocmask" }, /* examine and change blocked signals */ + /*PPM_SC_SIGPROCMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "sigprocmask" }, /* examine and change blocked signals */ /*PPM_SC_IPC*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "ipc" }, /*PPM_SC_SOCKETCALL*/ { EC_NET, (enum ppm_event_flags)(EF_NONE), "socketcall" }, - /*PPM_SC_STAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "stat64" }, - /*PPM_SC_LSTAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "lstat64" }, - /*PPM_SC_FSTAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fstat64" }, - /*PPM_SC_FCNTL64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "fcntl64" }, - /*PPM_SC_MMAP2*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mmap2" }, - /*PPM_SC__NEWSELECT*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "newselect" }, - /*PPM_SC_SGETMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sgetmask" }, /* manipulation of signal mask (obsolete) */ + /*PPM_SC_STAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "stat64" }, + /*PPM_SC_LSTAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "lstat64" }, + /*PPM_SC_FSTAT64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fstat64" }, + /*PPM_SC_FCNTL64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "fcntl64" }, + /*PPM_SC_MMAP2*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "mmap2" }, + /*PPM_SC__NEWSELECT*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "newselect" }, + /*PPM_SC_SGETMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "sgetmask" }, /* manipulation of signal mask (obsolete) */ /*PPM_SC_SSETMASK*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "ssetmask" }, /* manipulation of signal mask (obsolete) */ - /*PPM_SC_SIGPENDING*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sigpending" }, /* examine pending signals */ - /*PPM_SC_OLDUNAME*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "olduname" }, + /*PPM_SC_SIGPENDING*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "sigpending" }, /* examine pending signals */ + /*PPM_SC_OLDUNAME*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "olduname" }, /*PPM_SC_UMOUNT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "umount" }, /*PPM_SC_SIGNAL*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "signal" }, /*PPM_SC_NICE*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "nice" }, /* change process priority */ /*PPM_SC_STIME*/ { EC_TIME, (enum ppm_event_flags)(EF_NONE), "stime" }, - /*PPM_SC__LLSEEK*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "llseek" }, - /*PPM_SC_WAITPID*/ { EC_WAIT, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "waitpid" }, - /*PPM_SC_PREAD64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "pread64" }, - /*PPM_SC_PWRITE64*/ { EC_FILE, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "pwrite64" }, + /*PPM_SC__LLSEEK*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "llseek" }, + /*PPM_SC_WAITPID*/ { EC_WAIT, (enum ppm_event_flags)(EF_NONE), "waitpid" }, + /*PPM_SC_PREAD64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "pread64" }, + /*PPM_SC_PWRITE64*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "pwrite64" }, /*PPM_SC_ARCH_PRCTL*/ { EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "arch_prctl" }, /*PPM_SC_SHMAT*/ { EC_IPC, (enum ppm_event_flags)(EF_NONE), "shmat" }, - /*PPM_SC_SIGRETURN*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "sigreturn" }, /* return from signal handler and cleanup stack frame */ + /*PPM_SC_SIGRETURN*/ { EC_SIGNAL, (enum ppm_event_flags)(EF_NONE), "sigreturn" }, /* return from signal handler and cleanup stack frame */ /*PPM_SC_FALLOCATE*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "fallocate" }, /* manipulate file space */ - /*PPM_SC_NEWFSSTAT*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "newfstatat" }, + /*PPM_SC_NEWFSSTAT*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "newfstatat" }, /*PPM_SC_PROCESS_VM_READV*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "process_vm_readv" }, /*PPM_SC_PROCESS_VM_WRITEV*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "process_vm_writev" }, /*PPM_SC_FORK*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "fork" }, /*PPM_SC_VFORK*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "vfork" }, /*PPM_SC_SETUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "setuid" }, - /*PPM_SC_GETUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getuid" }, + /*PPM_SC_GETUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "getuid" }, /*PPM_SC_SETGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "setgid" }, - /*PPM_SC_GETEUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "geteuid" }, - /*PPM_SC_GETGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getgid" }, + /*PPM_SC_GETEUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "geteuid" }, + /*PPM_SC_GETGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "getgid" }, /*PPM_SC_SETRESUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "setresuid" }, - /*PPM_SC_SETRESGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "setresgid" }, - /*PPM_SC_GETRESUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getresuid" }, - /*PPM_SC_GETRESGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "getresgid" }, + /*PPM_SC_SETRESGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "setresgid" }, + /*PPM_SC_GETRESUID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "getresuid" }, + /*PPM_SC_GETRESGID32*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "getresgid" }, /*PPM_SC_FINIT_MODULE*/ { EC_SYSTEM, (enum ppm_event_flags)(EF_NONE), "finit_module" }, /* load a kernel module */ /*PPM_SC_BPF*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "bpf" }, /*PPM_SC_SECCOMP*/ { EC_OTHER, (enum ppm_event_flags)(EF_NONE), "seccomp" }, @@ -359,10 +359,10 @@ const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX] = { /*PPM_SC_CLONE*/ {EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "clone" }, /*PPM_SC_CLONE3*/ {EC_PROCESS, (enum ppm_event_flags)(EF_NONE), "clone3" }, /*PPM_SC_OPEN_BY_HANDLE_AT*/ { EC_FILE, (enum ppm_event_flags)(EF_NONE), "open_by_handle_at" }, - /*PPM_SC_IO_URING_SETUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_uring_setup" }, - /*PPM_SC_IO_URING_ENTER*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_uring_enter" }, - /*PPM_SC_IO_URING_REGISTER*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "io_uring_register" }, - /*PPM_SC_MLOCK2*/ {EC_MEMORY, (enum ppm_event_flags)(EF_DROP_SIMPLE_CONS), "mlock2"}, /* mlock2 locks part of the calling process's virtual address space int RAM*/ + /*PPM_SC_IO_URING_SETUP*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_uring_setup" }, + /*PPM_SC_IO_URING_ENTER*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_uring_enter" }, + /*PPM_SC_IO_URING_REGISTER*/ { EC_IO_OTHER, (enum ppm_event_flags)(EF_NONE), "io_uring_register" }, + /*PPM_SC_MLOCK2*/ {EC_MEMORY, (enum ppm_event_flags)(EF_NONE), "mlock2"}, /* mlock2 locks part of the calling process's virtual address space int RAM*/ }; bool validate_info_table_size() diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index e59616de37..2a7c5b5263 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -69,7 +69,6 @@ std::atomic sinsp::instance_count{0}; sinsp::sinsp(bool static_container, const std::string &static_id, const std::string &static_name, const std::string &static_image) : m_external_event_processor(), - m_simpleconsumer(false), m_evt(this), m_lastevent_ts(0), m_container_manager(this, static_container, static_id, static_name, static_image), @@ -467,6 +466,24 @@ void sinsp::set_import_users(bool import_users) m_usergroup_manager.m_import_users = import_users; } +void sinsp::set_syscalls_of_interest(std::unordered_set &syscalls_of_interest) +{ + m_ppm_sc_of_interest = syscalls_of_interest; +} + +void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) +{ + if (enabled) + { + m_ppm_sc_of_interest.insert(ppm_sc); + } + else + { + m_ppm_sc_of_interest.erase(ppm_sc); + + } +} + void sinsp::fill_syscalls_of_interest(scap_open_args *oargs) { // Fallback to set all events as interesting @@ -478,23 +495,6 @@ void sinsp::fill_syscalls_of_interest(scap_open_args *oargs) } } - /* - * in case of simple consumer (driver side) - * set all droppable events as non interesting (if they are syscall driven) - */ - if (m_simpleconsumer) - { - m_ppm_sc_of_interest.erase(PPM_SC_UNKNOWN); - - for (int i = 1; i < PPM_SC_MAX; i++) - { - if (g_infotables.m_syscall_info_table[i].flags & EF_DROP_SIMPLE_CONS) - { - m_ppm_sc_of_interest.erase(i); - } - } - } - // Finally, set scap_open_args syscalls_of_interest for (int i = 0; i < PPM_SC_MAX; i++) { @@ -682,11 +682,6 @@ std::string sinsp::generate_gvisor_config(std::string socket_path) return gvisor_config::generate(socket_path); } -void sinsp::set_simple_consumer() -{ - m_simpleconsumer = true; -} - int64_t sinsp::get_file_size(const std::string& fname, char *error) { static string err_str = "Could not determine capture file size: "; @@ -717,16 +712,6 @@ int64_t sinsp::get_file_size(const std::string& fname, char *error) return -1; } -void sinsp::set_simpledriver_mode() -{ -#ifndef _WIN32 - if(scap_enable_simpledriver_mode(m_h) != SCAP_SUCCESS) - { - throw sinsp_exception(scap_getlasterr(m_h)); - } -#endif -} - unsigned sinsp::m_num_possible_cpus = 0; unsigned sinsp::num_possible_cpus() diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index dbe9e7d524..2dfb7dc3fe 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -854,12 +854,8 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source sinsp_parser* get_parser(); - /*! - \brief Enables simple_consumer mode on sinsp, at driver level. - This will avoid tracing syscalls flagged with EF_DROP_SIMPLE_CONS. - Must be called before sinsp opening. - */ - void set_simple_consumer(); + void set_syscalls_of_interest(std::unordered_set &syscalls_of_interest); + void mark_syscall_of_interest(uint32_t ppm_sc, bool enabled = true); bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress); void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo); @@ -878,7 +874,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source scap_refresh_proc_table(m_h); } - void set_simpledriver_mode(); std::vector get_n_tracepoint_hit(); void set_bpf_probe(const std::string& bpf_probe); @@ -960,7 +955,7 @@ VISIBILITY_PRIVATE static inline ppm_event_flags simple_consumer_skip_flags() { - return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED | EF_DROP_SIMPLE_CONS | EF_OLD_VERSION); + return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED | EF_OLD_VERSION); } // Doxygen doesn't understand VISIBILITY_PRIVATE #ifdef _DOXYGEN @@ -1030,8 +1025,6 @@ VISIBILITY_PRIVATE uint64_t m_nevts; int64_t m_filesize; - bool m_simpleconsumer; - scap_mode_t m_mode = SCAP_MODE_NONE; // If non-zero, reading from this fd and m_input_filename contains "fd From 9b993d33bb5e31aa1a6d3e0b7c1156b8dabd28c6 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 3 Aug 2022 12:19:08 +0200 Subject: [PATCH 02/29] new(driver, userspace/libscap): add a new scap_open argument to choose set of tracepoints to be attached. Updated kmod adding a new ioctl to control this new feature; for bpf and modern_bpf the feature works in a very simple way, by just avoid attaching the tracepoint programs when not requested. Moreover, updated scap_open_args API: now both tp_of_interest and syscalls_of_interest are NULLable pointers. When NULL, by default all available tps are attached, and all syscalls are interesting. Updated sinsp to manage this new scap_open_args implementation. Finally, updated libscap scap-open example to manage tracepoints and syscalls of interest. Signed-off-by: Federico Di Pierro --- driver/CMakeLists.txt | 1 + driver/main.c | 261 +++++++++++++++--- driver/ppm_events_public.h | 1 + driver/ppm_tp.h | 20 ++ userspace/libscap/engine/bpf/scap_bpf.c | 56 +++- userspace/libscap/engine/kmod/scap_kmod.c | 27 +- .../libscap/examples/01-open/scap_open.c | 84 +++++- userspace/libscap/scap.c | 11 + userspace/libscap/scap_engine_util.c | 3 +- userspace/libscap/scap_open.h | 118 ++++---- userspace/libsinsp/sinsp.cpp | 11 +- 11 files changed, 483 insertions(+), 110 deletions(-) create mode 100644 driver/ppm_tp.h diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index c2e8a32f93..e0502623f4 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -111,6 +111,7 @@ set(DRIVER_SOURCES ppm_compat_unistd_32.h ppm_version.h systype_compat.h + ppm_tp.h ) foreach(FILENAME IN LISTS DRIVER_SOURCES) diff --git a/driver/main.c b/driver/main.c index af7766d3c0..f2269de36d 100644 --- a/driver/main.c +++ b/driver/main.c @@ -55,6 +55,7 @@ or GPL2.txt for full copies of the license. #include "ppm_events_public.h" #include "ppm_events.h" #include "ppm.h" +#include "ppm_tp.h" #if defined(CONFIG_IA32_EMULATION) && !defined(__NR_ia32_socketcall) #include "ppm_compat_unistd_32.h" #endif @@ -205,7 +206,7 @@ static const struct file_operations g_ppm_fops = { */ LIST_HEAD(g_consumer_list); static DEFINE_MUTEX(g_consumer_mutex); -static bool g_tracepoint_registered; +static uint32_t g_tracepoints_attached; // list of attached tracepoints; bitmask using ppm_tp.h enum #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) static struct tracepoint *tp_sys_enter; @@ -224,7 +225,6 @@ static struct tracepoint *tp_signal_deliver; // disabled so check if g_fault_tracepoint_disabled is set. static struct tracepoint *tp_page_fault_user; static struct tracepoint *tp_page_fault_kernel; -static bool g_fault_tracepoint_registered; static bool g_fault_tracepoint_disabled; #endif @@ -494,7 +494,7 @@ static int ppm_open(struct inode *inode, struct file *filp) reset_ring_buffer(ring); ring->open = true; - if (!g_tracepoint_registered) { + if (g_tracepoints_attached == 0) { pr_info("starting capture\n"); /* * Enable the tracepoints @@ -508,10 +508,12 @@ static int ppm_open(struct inode *inode, struct file *filp) #else ret = register_trace_syscall_exit(syscall_exit_probe); #endif - if (ret) { + if(ret) + { pr_err("can't create the sys_exit tracepoint\n"); goto err_sys_exit; } + g_tracepoints_attached |= 1 << SYS_EXIT; /* * SYS_ENTER @@ -521,29 +523,35 @@ static int ppm_open(struct inode *inode, struct file *filp) #else ret = register_trace_syscall_enter(syscall_enter_probe); #endif - if (ret) { + if(ret) + { pr_err("can't create the sys_enter tracepoint\n"); goto err_sys_enter; } + g_tracepoints_attached |= 1 << SYS_ENTER; /* * SCHED_PROCESS_EXIT */ ret = compat_register_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); - if (ret) { + if(ret) + { pr_err("can't create the sched_process_exit tracepoint\n"); goto err_sched_procexit; } + g_tracepoints_attached |= 1 << SCHED_PROC_EXIT; /* * CAPTURE_CONTEXT_SWITCHES */ #ifdef CAPTURE_CONTEXT_SWITCHES ret = compat_register_trace(sched_switch_probe, "sched_switch", tp_sched_switch); - if (ret) { + if(ret) + { pr_err("can't create the sched_switch tracepoint\n"); goto err_sched_switch; } + g_tracepoints_attached |= 1 << SCHED_SWITCH; #endif /* @@ -551,10 +559,12 @@ static int ppm_open(struct inode *inode, struct file *filp) */ #ifdef CAPTURE_SIGNAL_DELIVERIES ret = compat_register_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - if (ret) { + if(ret) + { pr_err("can't create the signal_deliver tracepoint\n"); goto err_signal_deliver; } + g_tracepoints_attached |= 1 << SIGNAL_DELIVER; #endif /* @@ -562,10 +572,12 @@ static int ppm_open(struct inode *inode, struct file *filp) */ #ifdef CAPTURE_SCHED_PROC_EXEC ret = compat_register_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); - if (ret) { + if(ret) + { pr_err("can't create the 'sched_proc_exec' tracepoint\n"); goto err_sched_proc_exec; } + g_tracepoints_attached |= 1 << SCHED_PROC_EXEC; #endif /* @@ -573,12 +585,13 @@ static int ppm_open(struct inode *inode, struct file *filp) */ #ifdef CAPTURE_SCHED_PROC_FORK ret = compat_register_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); - if (ret) { + if(ret) + { pr_err("can't create the 'sched_proc_fork' tracepoint\n"); goto err_sched_proc_fork; } + g_tracepoints_attached |= 1 << SCHED_PROC_FORK; #endif - g_tracepoint_registered = true; } ret = 0; @@ -640,6 +653,7 @@ static int ppm_open(struct inode *inode, struct file *filp) #else unregister_trace_syscall_exit(syscall_exit_probe); #endif + g_tracepoints_attached = 0; err_sys_exit: ring->open = false; @@ -719,55 +733,73 @@ static int ppm_release(struct inode *inode, struct file *filp) * The last closed device stops event collection */ if (list_empty(&g_consumer_list)) { - if (g_tracepoint_registered) { + if (g_tracepoints_attached != 0) { pr_info("no more consumers, stopping capture\n"); /* * SYS_EXIT */ + if ((g_tracepoints_attached & (1 << SYS_EXIT))) + { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); + compat_unregister_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); #else - unregister_trace_syscall_exit(syscall_exit_probe); + unregister_trace_syscall_exit(syscall_exit_probe); #endif + } /* * SYS_ENTER - */ + */ + if ((g_tracepoints_attached & (1 << SYS_ENTER))) + { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); + compat_unregister_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); #else - unregister_trace_syscall_enter(syscall_enter_probe); + unregister_trace_syscall_enter(syscall_enter_probe); #endif + } /* * SCHED_PROCESS_EXIT - */ - compat_unregister_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); + */ + if ((g_tracepoints_attached & (1 << SCHED_PROC_EXIT))) + { + compat_unregister_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); + } /* * CAPTURE_CONTEXT_SWITCHES */ #ifdef CAPTURE_CONTEXT_SWITCHES - compat_unregister_trace(sched_switch_probe, "sched_switch", tp_sched_switch); + if ((g_tracepoints_attached & (1 << SCHED_SWITCH))) + { + compat_unregister_trace(sched_switch_probe, "sched_switch", tp_sched_switch); + } #endif /* * CAPTURE_SIGNAL_DELIVERIES */ + #ifdef CAPTURE_SIGNAL_DELIVERIES - compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); + if ((g_tracepoints_attached & (1 << SIGNAL_DELIVER))) + { + compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); + } #endif /* * CAPTURE_PAGE_FAULTS */ #ifdef CAPTURE_PAGE_FAULTS - if (g_fault_tracepoint_registered) + if (g_tracepoints_attached & (1 << PAGE_FAULT_USER)) { compat_unregister_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); + } + if (g_tracepoints_attached & (1 << PAGE_FAULT_KERN)) + { compat_unregister_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); - g_fault_tracepoint_registered = false; } #endif @@ -775,20 +807,26 @@ static int ppm_release(struct inode *inode, struct file *filp) * CAPTURE_SCHED_PROC_EXEC */ #ifdef CAPTURE_SCHED_PROC_EXEC - compat_unregister_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); + if (g_tracepoints_attached & (1 << SCHED_PROC_EXEC)) + { + compat_unregister_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); + } #endif /* * CAPTURE_SCHED_PROC_FORK */ #ifdef CAPTURE_SCHED_PROC_FORK - compat_unregister_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); + if (g_tracepoints_attached & (1 << SCHED_PROC_FORK)) + { + compat_unregister_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); + } #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) tracepoint_synchronize_unregister(); #endif - g_tracepoint_registered = false; + g_tracepoints_attached = 0; /* * Reset tracepoint counter @@ -809,6 +847,147 @@ static int ppm_release(struct inode *inode, struct file *filp) return ret; } +static int force_tp_set(int new_tp_set) +{ + u32 idx; + u32 new_val; + u32 curr_val; + for(idx = 0; idx < TP_VAL_MAX; idx++) + { + new_val = new_tp_set & (1 << idx); + curr_val = g_tracepoints_attached & (1 << idx); + if((new_val ^ curr_val) == 0) + { + // no change needed + continue; + } + switch(idx) + { + case SYS_ENTER: + if(new_val) + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) + compat_register_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); +#else + register_trace_syscall_enter(syscall_enter_probe); +#endif + } + else + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) + compat_unregister_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); +#else + unregister_trace_syscall_enter(syscall_enter_probe); +#endif + } + break; + case SYS_EXIT: + if(new_val) + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) + compat_register_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); +#else + register_trace_syscall_exit(syscall_exit_probe); +#endif + } + else + { +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) + compat_unregister_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); +#else + unregister_trace_syscall_exit(syscall_exit_probe); +#endif + } + break; + case SCHED_PROC_EXIT: + if (new_val) + { + compat_register_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); + } + else + { + compat_unregister_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); + } + break; +#ifdef CAPTURE_CONTEXT_SWITCHES + case SCHED_SWITCH: + if (new_val) + { + compat_register_trace(sched_switch_probe, "sched_switch", tp_sched_switch); + } + else + { + compat_unregister_trace(sched_switch_probe, "sched_switch", tp_sched_switch); + } + break; +#endif +#ifdef CAPTURE_PAGE_FAULTS + case PAGE_FAULT_USER: + if (new_val) + { + compat_register_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); + } + else + { + compat_unregister_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); + } + break; + case PAGE_FAULT_KERN: + if (new_val) + { + compat_register_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); + } + else + { + compat_unregister_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); + } + break; +#endif +#ifdef CAPTURE_SIGNAL_DELIVERIES + case SIGNAL_DELIVER: + if (new_val) + { + compat_register_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); + } + else + { + compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); + } + break; +#endif +#ifdef CAPTURE_SCHED_PROC_FORK + case SCHED_PROC_FORK: + if (new_val) + { + compat_register_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); + } + else + { + compat_unregister_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); + } + break; +#endif +#ifdef CAPTURE_SCHED_PROC_EXEC + case SCHED_PROC_EXEC: + if (new_val) + { + compat_register_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); + } + else + { + compat_unregister_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); + } + break; +#endif + default: + // unmanaged idx + break; + } + } + g_tracepoints_attached = new_tp_set; + return 0; // TODO error handling +} + static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int cpu; @@ -1225,7 +1404,7 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case PPM_IOCTL_DISABLE_SIGNAL_DELIVER: { vpr_info("PPM_IOCTL_DISABLE_SIGNAL_DELIVER\n"); - if (g_tracepoint_registered) + if (g_tracepoints_attached & (1 << SIGNAL_DELIVER)) compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); ret = 0; goto cleanup_ioctl; @@ -1233,7 +1412,7 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case PPM_IOCTL_ENABLE_SIGNAL_DELIVER: { vpr_info("PPM_IOCTL_ENABLE_SIGNAL_DELIVER\n"); - if (g_tracepoint_registered) + if (!(g_tracepoints_attached & (1 << SIGNAL_DELIVER))) compat_register_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); ret = 0; goto cleanup_ioctl; @@ -1250,7 +1429,7 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { vpr_info("PPM_IOCTL_ENABLE_PAGE_FAULTS\n"); #ifdef CAPTURE_PAGE_FAULTS - ASSERT(g_tracepoint_registered); + ASSERT(g_tracepoint_attached > 0); if (g_fault_tracepoint_disabled) { pr_err("kernel page fault tracepoints are disabled\n"); @@ -1258,22 +1437,28 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto cleanup_ioctl; } - if (!g_fault_tracepoint_registered) { + if (!(g_tracepoints_attached & (1 << PAGE_FAULT_USER))) + { ret = compat_register_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); - if (ret) { + if(ret) + { pr_err("can't create the page_fault_user tracepoint\n"); ret = -EINVAL; goto cleanup_ioctl; } + g_tracepoints_attached |= 1 << PAGE_FAULT_USER; + } + if (!(g_tracepoints_attached & (1 << PAGE_FAULT_KERN))) + { ret = compat_register_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); - if (ret) { + if(ret) + { pr_err("can't create the page_fault_kernel tracepoint\n"); ret = -EINVAL; goto err_page_fault_kernel; } - - g_fault_tracepoint_registered = true; + g_tracepoints_attached |= 1 << PAGE_FAULT_KERN; } ret = 0; @@ -1284,6 +1469,11 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto cleanup_ioctl; #endif } + case PPM_IOCTL_MANAGE_TP: + { + ret = force_tp_set( (u32)arg); + goto cleanup_ioctl; + } default: ret = -ENOTTY; goto cleanup_ioctl; @@ -1292,6 +1482,7 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) #ifdef CAPTURE_PAGE_FAULTS err_page_fault_kernel: compat_unregister_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); + g_tracepoints_attached &= ~(1 << PAGE_FAULT_USER); #endif cleanup_ioctl: mutex_unlock(&g_consumer_mutex); @@ -2981,7 +3172,7 @@ int scap_init(void) /* * All ok. Final initializations. */ - g_tracepoint_registered = false; + g_tracepoints_attached = 0; return 0; diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 87be72e850..8a0a99ff1b 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -1718,6 +1718,7 @@ struct ppm_evt_hdr { #define PPM_IOCTL_SET_STATSD_PORT _IO(PPM_IOCTL_MAGIC, 23) #define PPM_IOCTL_GET_API_VERSION _IO(PPM_IOCTL_MAGIC, 24) #define PPM_IOCTL_GET_SCHEMA_VERSION _IO(PPM_IOCTL_MAGIC, 25) +#define PPM_IOCTL_MANAGE_TP _IO(PPM_IOCTL_MAGIC, 26) #endif // CYGWING_AGENT extern const struct ppm_name_value socket_families[]; diff --git a/driver/ppm_tp.h b/driver/ppm_tp.h new file mode 100644 index 0000000000..8f7145884b --- /dev/null +++ b/driver/ppm_tp.h @@ -0,0 +1,20 @@ +#pragma once + +/* | name | name | */ +#define TP_FIELDS \ + X(SYS_ENTER, "sys_enter") \ + X(SYS_EXIT, "sys_exit") \ + X(SCHED_PROC_EXIT, "sched_process_exit") \ + X(SCHED_SWITCH, "sched_switch") \ + X(PAGE_FAULT_USER, "page_fault_user") \ + X(PAGE_FAULT_KERN, "page_fault_kernel") \ + X(SIGNAL_DELIVER, "signal_deliver") \ + X(SCHED_PROC_FORK, "sched_process_fork") \ + X(SCHED_PROC_EXEC, "sched_process_exec") + +typedef enum { +#define X(name, path) name, + TP_FIELDS +#undef X + TP_VAL_MAX, +} tp_values; \ No newline at end of file diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 4632a3394a..1c0b43f60f 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -644,10 +644,50 @@ static int32_t load_tracepoint(struct bpf_engine* handle, const char *event, str return SCAP_SUCCESS; } +static tp_values tp_from_name(const char *tp_path) +{ + static const char *names[] = { +#define X(name, path) path, + TP_FIELDS +#undef X + }; + + // Find last '/' occurrence to take only the basename + const char *tp_name = strrchr(tp_path, '/'); + if (tp_name && strlen(tp_name) > 1) + { + tp_name++; + for (int i = 0; i < TP_VAL_MAX; i++) + { + if (strcmp(tp_name, names[i]) == 0) + { + return i; + } + } + } + return -1; +} + +static bool is_tp_enabled(interesting_tp_set *tp_of_interest, const char *shname) +{ + if (tp_of_interest) + { + tp_values val = tp_from_name(shname); + if(val == -1) + { + // Not found? Enable it! + return true; + } + return tp_of_interest->tp[val]; + } + return true; +} + static int32_t load_bpf_file( struct bpf_engine *handle, const char *path, uint64_t *api_version_p, - uint64_t *schema_version_p) + uint64_t *schema_version_p, + interesting_tp_set *tp_of_interest) { int j; int maps_shndx = 0; @@ -805,9 +845,12 @@ static int32_t load_bpf_file( if(memcmp(shname, "tracepoint/", sizeof("tracepoint/") - 1) == 0 || memcmp(shname, "raw_tracepoint/", sizeof("raw_tracepoint/") - 1) == 0) { - if(load_tracepoint(handle, shname, data->d_buf, data->d_size) != SCAP_SUCCESS) + if (is_tp_enabled(tp_of_interest, shname)) { - goto cleanup; + if(load_tracepoint(handle, shname, data->d_buf, data->d_size) != SCAP_SUCCESS) + { + goto cleanup; + } } } } @@ -1428,7 +1471,8 @@ int32_t scap_bpf_load( struct bpf_engine *handle, const char *bpf_probe, uint64_t *api_version_p, - uint64_t *schema_version_p) + uint64_t *schema_version_p, + interesting_tp_set *tp_of_interest) { int online_cpu; int j; @@ -1447,7 +1491,7 @@ int32_t scap_bpf_load( return SCAP_FAILURE; } - if(load_bpf_file(handle, bpf_probe, api_version_p, schema_version_p) != SCAP_SUCCESS) + if(load_bpf_file(handle, bpf_probe, api_version_p, schema_version_p, tp_of_interest) != SCAP_SUCCESS) { return SCAP_FAILURE; } @@ -1768,7 +1812,7 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) return rc; } - rc = scap_bpf_load(engine.m_handle, bpf_probe_buf, &handle->m_api_version, &handle->m_schema_version); + rc = scap_bpf_load(engine.m_handle, bpf_probe_buf, &handle->m_api_version, &handle->m_schema_version, &oargs->tp_of_interest); if(rc != SCAP_SUCCESS) { return rc; diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index 6bd5708ac5..51cb68281b 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -108,7 +108,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) { return rc; } - fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, handle->syscalls_of_interest); + fill_syscalls_of_interest(oargs->ppm_sc_of_interest, handle->syscalls_of_interest); // // Allocate the device descriptors. @@ -249,6 +249,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) ++j; } + // Set interesting syscalls for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) { if (!handle->syscalls_of_interest[i]) @@ -256,15 +257,27 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) // Kmod driver event_mask check uses event_types instead of syscall nr enum ppm_event_type enter_ev = g_syscall_table[i].enter_event_type; enum ppm_event_type exit_ev = g_syscall_table[i].exit_event_type; - // Filter unmapped syscalls (that have a g_syscall_table entry with both enter_ev and exit_ev 0ed) - if (enter_ev != 0 && exit_ev != 0) - { - scap_unset_eventmask(handle, enter_ev); - scap_unset_eventmask(handle, exit_ev); - } + scap_unset_eventmask(handle, enter_ev); + scap_unset_eventmask(handle, exit_ev); } } + // Set interesting Tracepoints + uint32_t tp_of_interest = 0; + for (int i = 0; i < TP_VAL_MAX; i++) + { + if (!oargs->tp_of_interest || oargs->tp_of_interest->tp[i]) + { + tp_of_interest |= (1 << i); + } + } + if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_MANAGE_TP, tp_of_interest)) + { + strncpy(handle->m_lasterr, "PPM_IOCTL_MANAGE_TP failed", SCAP_LASTERR_SIZE); + ASSERT(false); + return SCAP_FAILURE; + } + return SCAP_SUCCESS; } diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index ebda6134bf..651af1c004 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -25,6 +25,8 @@ limitations under the License. #define BPF_OPTION "--bpf" #define MODERN_BPF_OPTION "--modern_bpf" #define SCAP_FILE_OPTION "--scap_file" +#define TP_OPTION "--tp" +#define PPM_SC_OPTION "--ppm_sc" #define NUM_EVENTS_OPTION "--num_events" #define EVENT_TYPE_OPTION "--evt_type" #define VALIDATION_OPTION "--validate_syscalls" @@ -47,6 +49,10 @@ struct scap_savefile_engine_params savefile_params; /* Configuration variables set through CLI. */ uint64_t num_events = UINT64_MAX; /* max number of events to catch. */ int evt_type = -1; /* event type to print. */ +interesting_tp_set tp_of_interest; +bool tp_is_set; +interesting_ppm_sc_set ppm_sc_of_interest; +bool ppm_sc_is_set; /* Generic global variables. */ scap_open_args oargs = {.engine_name = UNKNOWN_ENGINE}; /* scap oargs used in `scap_open`. */ @@ -55,6 +61,50 @@ scap_t* g_h = NULL; /* global scap handler. */ uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ char* valptr = NULL; /* pointer used to print the value of event params. */ +void enable_single_tp(const char *tp_basename) +{ + static const char *names[] = { +#define X(name, tp_path) tp_path, + TP_FIELDS +#undef X + }; + + bool found = false; + for (int i = 0; i < TP_VAL_MAX && !found; i++) + { + if (strcmp(names[i], tp_basename) == 0) + { + tp_of_interest.tp[i] = true; + found = true; + } + } + if (!found) + { + fprintf(stderr, "Tracepoint '%s' not found. Unsupported or wrong parameter?\n", tp_basename); + fprintf(stderr, "Please choose between:\n"); + for (int i = 0; i < TP_VAL_MAX; i++) + { + fprintf(stderr, "\t* %s\n", names[i]); + } + exit(EXIT_FAILURE); + } + else + { + tp_is_set = true; + } +} + +void enable_single_ppm_sc(int ppm_sc_code) +{ + if (ppm_sc_code < 0 || ppm_sc_code >= PPM_SC_MAX) + { + fprintf(stderr, "Unexistent ppm_sc code: %d. Wrong parameter?\n", ppm_sc_code); + exit(EXIT_FAILURE); + } + ppm_sc_of_interest.ppm_sc[ppm_sc_code] = true; + ppm_sc_is_set = true; +} + /*=============================== PRINT EVENT PARAMS ===========================*/ void print_ipv4(int starting_index) @@ -491,6 +541,8 @@ void print_help() printf("'%s': enable modern BPF probe.\n", MODERN_BPF_OPTION); printf("'%s ': read events from scap file.\n", SCAP_FILE_OPTION); printf("\n------> CONFIGURATIONS OPTIONS\n"); + printf("'%s ': enable only requested tracepoint. Can be passed multiple times.\n", TP_OPTION); + printf("'%s ': enable only requested syscall. Can be passed multiple times.\n", PPM_SC_OPTION); printf("'%s ': number of events to catch before terminating. (default: UINT64_MAX)\n", NUM_EVENTS_OPTION); printf("'%s ': every event of this type will be printed to console. (default: -1, no print)\n", EVENT_TYPE_OPTION); printf("\n------> VALIDATION OPTIONS\n"); @@ -615,6 +667,25 @@ void parse_CLI_options(int argc, char** argv) /*=============================== SCAP SOURCES ===========================*/ /*=============================== CONFIGURATIONS ===========================*/ + if(!strcmp(argv[i], TP_OPTION)) + { + if(!(i + 1 < argc)) + { + printf("\nYou need to specify also the basename of the tracepoint you are interested in! Bye!\n"); + exit(EXIT_FAILURE); + } + enable_single_tp(argv[++i]); + } + + if(!strcmp(argv[i], PPM_SC_OPTION)) + { + if(!(i + 1 < argc)) + { + printf("\nYou need to specify also the syscall ppm_sc code! Bye!\n"); + exit(EXIT_FAILURE); + } + enable_single_ppm_sc(atoi(argv[++i])); + } if(!strcmp(argv[i], NUM_EVENTS_OPTION)) { @@ -721,13 +792,16 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - /* Interesting syscalls by default. */ - for(int j = 0; j < PPM_SC_MAX; j++) + parse_CLI_options(argc, argv); + + if (ppm_sc_is_set) { - oargs.ppm_sc_of_interest.ppm_sc[j] = 1; + oargs.ppm_sc_of_interest = ppm_sc_of_interest; + } + if (tp_is_set) + { + oargs.tp_of_interest = tp_of_interest; } - - parse_CLI_options(argc, argv); print_scap_source(); diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index a356f52cc8..4d1c9c00f0 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -83,7 +83,18 @@ static int32_t copy_comms(scap_t *handle, const char **suppressed_comms) } #if !defined(HAS_CAPTURE) || defined(CYGWING_AGENT) || defined(_WIN32) +<<<<<<< HEAD scap_t* scap_open_live_int(char *error, int32_t *rc, scap_open_args* oargs) +======= +scap_t* scap_open_live_int(char *error, int32_t *rc, + proc_entry_callback proc_callback, + void* proc_callback_context, + bool import_users, + const char *bpf_probe, + const char **suppressed_comms, + interesting_ppm_sc_set *ppm_sc_of_interest, + interesting_tp_set *tp_of_interest) +>>>>>>> 717ab7c5 (new(driver, userspace/libscap): add a new scap_open argument to choose set of tracepoints to be attached.) { snprintf(error, SCAP_LASTERR_SIZE, "live capture not supported on %s", PLATFORM_NAME); *rc = SCAP_NOT_SUPPORTED; diff --git a/userspace/libscap/scap_engine_util.c b/userspace/libscap/scap_engine_util.c index fef4d648ff..12d3c497ab 100644 --- a/userspace/libscap/scap_engine_util.c +++ b/userspace/libscap/scap_engine_util.c @@ -25,7 +25,6 @@ limitations under the License. #include "driver_config.h" #endif -/* `ppm_sc_of_interest` is never `NULL`, we check it before calling this method. */ void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest) { for (int i = 0; i < PPM_SC_MAX; i++) @@ -36,7 +35,7 @@ void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool // Find the match between the ppm_sc and the syscall_nr if(g_syscall_code_routing_table[syscall_nr] == i) { - if (ppm_sc_of_interest->ppm_sc[i]) + if (!ppm_sc_of_interest || ppm_sc_of_interest->ppm_sc[i]) { syscalls_of_interest[syscall_nr] = true; } diff --git a/userspace/libscap/scap_open.h b/userspace/libscap/scap_open.h index 56dc608233..2be5a3079d 100644 --- a/userspace/libscap/scap_open.h +++ b/userspace/libscap/scap_open.h @@ -29,65 +29,83 @@ limitations under the License. #include "scap_procs.h" #include "scap_test.h" #include "../../driver/ppm_events_public.h" +#include "../../driver/ppm_tp.h" #ifdef __cplusplus +<<<<<<< HEAD extern "C" -{ +======= +extern "C" { #endif +/*! + \brief Arguments for scap_open +*/ +typedef enum { /*! - \brief Scap possible modes - */ - typedef enum - { - /*! - * Default value that mostly exists so that sinsp can have a valid value - * before it is initialized. - */ - SCAP_MODE_NONE = 0, - /*! - * Read system call data from a capture file. - */ - SCAP_MODE_CAPTURE, - /*! - * Read system call data from the underlying operating system. - */ - SCAP_MODE_LIVE, - /*! - * Do not read system call data. If next is called, a dummy event is - * returned. - */ - SCAP_MODE_NODRIVER, - /*! - * Do not read system call data. Events come from the configured input plugin. - */ - SCAP_MODE_PLUGIN, - } scap_mode_t; - + * Default value that mostly exists so that sinsp can have a valid value + * before it is initialized. + */ + SCAP_MODE_NONE = 0, + /*! + * Read system call data from a capture file. + */ + SCAP_MODE_CAPTURE, + /*! + * Read system call data from the underlying operating system. + */ + SCAP_MODE_LIVE, + /*! + * Do not read system call data. If next is called, a dummy event is + * returned. + */ + SCAP_MODE_NODRIVER, + /*! + * Do not read system call data. Events come from the configured input plugin. + */ + SCAP_MODE_PLUGIN, +#ifdef HAS_ENGINE_MODERN_BPF /*! - * \brief Argument for scap_open - * Set any PPM_SC syscall idx to true to enable its tracing at driver level, - * otherwise syscalls are not traced (so called "uninteresting syscalls"). + * Read system call data from the underlying operating system using a modern + * bpf probe. */ - typedef struct - { - bool ppm_sc[PPM_SC_MAX]; - } interesting_ppm_sc_set; + SCAP_MODE_MODERN_BPF, +#endif +} scap_mode_t; - typedef struct scap_open_args - { - const char* engine_name; ///< engine name ("kmod", "bpf", ...). - scap_mode_t mode; ///< scap-mode required by the engine. - proc_entry_callback proc_callback; ///< Callback to be invoked for each thread/fd that is extracted from /proc, or NULL if no callback is needed. - void* proc_callback_context; ///< Opaque pointer that will be included in the calls to proc_callback. Ignored if proc_callback is NULL. - bool import_users; ///< true if the user list should be created when opening the capture. - const char* suppressed_comms[SCAP_MAX_SUPPRESSED_COMMS]; ///< A list of processes (comm) for which no - // events should be returned, with a trailing NULL value. - // You can provide additional comm - // values via scap_suppress_events_comm(). - interesting_ppm_sc_set ppm_sc_of_interest; ///< syscalls of interest. - void* engine_params; ///< engine-specific params. - } scap_open_args; +/*! + \brief Argument for scap_open + Set any PPM_SC syscall idx to true to enable its tracing at driver level, + otherwise syscalls are not traced (so called "uninteresting syscalls"). +*/ +typedef struct { + bool ppm_sc[PPM_SC_MAX]; +} interesting_ppm_sc_set; + +/*! + \brief Argument for scap_open + Set any tracepoint idx to true to enable its tracing at driver level, + otherwise a tp is not attached (so called "uninteresting tracepoint"). +*/ +typedef struct { + bool tp[TP_VAL_MAX]; +} interesting_tp_set; + +typedef struct scap_open_args +{ + const char* engine_name; ///< engine name ("kmod", "bpf", ...). + scap_mode_t mode; ///< scap-mode required by the engine. + proc_entry_callback proc_callback; ///< Callback to be invoked for each thread/fd that is extracted from /proc, or NULL if no callback is needed. + void* proc_callback_context; ///< Opaque pointer that will be included in the calls to proc_callback. Ignored if proc_callback is NULL. + bool import_users; ///< true if the user list should be created when opening the capture. + const char* suppressed_comms[SCAP_MAX_SUPPRESSED_COMMS]; ///< A list of processes (comm) for which no + // events should be returned, with a trailing NULL value. + // You can provide additional comm + // values via scap_suppress_events_comm(). + interesting_ppm_sc_set ppm_sc_of_interest; ///< syscalls of interest. + interesting_tp_set tp_of_interest; ///< tp of interest + void* engine_params; ///< engine-specific params. +} scap_open_args; #ifdef __cplusplus } diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 2a7c5b5263..2db1a84556 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -489,17 +489,18 @@ void sinsp::fill_syscalls_of_interest(scap_open_args *oargs) // Fallback to set all events as interesting if (m_mode != SCAP_MODE_LIVE || m_ppm_sc_of_interest.empty()) { - for(int i = 0; i < PPM_SC_MAX; i++) - { - m_ppm_sc_of_interest.insert(i); - } + // Default NULL value will handle everything for us + return; } + static interesting_ppm_sc_set ppm_sc_of_interest; + // Finally, set scap_open_args syscalls_of_interest for (int i = 0; i < PPM_SC_MAX; i++) { - oargs->ppm_sc_of_interest.ppm_sc[i] = m_ppm_sc_of_interest.find(i) != m_ppm_sc_of_interest.end(); + ppm_sc_of_interest.ppm_sc[i] = m_ppm_sc_of_interest.find(i) != m_ppm_sc_of_interest.end(); } + oargs->ppm_sc_of_interest = &ppm_sc_of_interest; } void sinsp::open_common(scap_open_args* oargs) From db62a72d22df14e544371ac166e65b23ac807542 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 4 Aug 2022 09:29:28 +0200 Subject: [PATCH 03/29] chore(driver,userspace/libscap,userspace/libsinsp): refactored kmod main.c to always use newly introduced `force_tp_set` function to set/unset tracepoints. This leads to a much cleaner code. Moreover, now tp_table exports tp_names string array, that is used by scap_bpf, kmod and scap-open. Finally, renamed a bunch of simple_consumer references in function names in libsinsp. Signed-off-by: Federico Di Pierro --- driver/CMakeLists.txt | 1 + driver/Makefile.in | 2 +- driver/main.c | 416 ++++-------------- driver/ppm_tp.h | 4 +- driver/tp_table.c | 7 + userspace/libscap/CMakeLists.txt | 3 +- userspace/libscap/engine/bpf/scap_bpf.c | 9 +- .../libscap/examples/01-open/scap_open.c | 10 +- userspace/libsinsp/event.cpp | 6 +- userspace/libsinsp/event.h | 5 +- userspace/libsinsp/fields_info.cpp | 2 +- userspace/libsinsp/sinsp.cpp | 1 - userspace/libsinsp/sinsp.h | 10 +- 13 files changed, 107 insertions(+), 369 deletions(-) create mode 100644 driver/tp_table.c diff --git a/driver/CMakeLists.txt b/driver/CMakeLists.txt index e0502623f4..df50976f98 100644 --- a/driver/CMakeLists.txt +++ b/driver/CMakeLists.txt @@ -112,6 +112,7 @@ set(DRIVER_SOURCES ppm_version.h systype_compat.h ppm_tp.h + tp_table.c ) foreach(FILENAME IN LISTS DRIVER_SOURCES) diff --git a/driver/Makefile.in b/driver/Makefile.in index 84f60e064b..a0791c7cad 100644 --- a/driver/Makefile.in +++ b/driver/Makefile.in @@ -5,7 +5,7 @@ # MIT.txt or GPL.txt for full copies of the license. # -@DRIVER_NAME@-y += main.o dynamic_params_table.o fillers_table.o flags_table.o ppm_events.o ppm_fillers.o event_table.o syscall_table.o ppm_cputime.o +@DRIVER_NAME@-y += main.o dynamic_params_table.o fillers_table.o flags_table.o ppm_events.o ppm_fillers.o event_table.o syscall_table.o ppm_cputime.o tp_table.o obj-m += @DRIVER_NAME@.o ccflags-y := @KBUILD_FLAGS@ diff --git a/driver/main.c b/driver/main.c index f2269de36d..2e10ab6848 100644 --- a/driver/main.c +++ b/driver/main.c @@ -136,6 +136,7 @@ struct event_data_t { */ static int ppm_open(struct inode *inode, struct file *filp); static int ppm_release(struct inode *inode, struct file *filp); +static int force_tp_set(u32 new_tp_set, u32 max_val); static long ppm_ioctl(struct file *f, unsigned int cmd, unsigned long arg); static int ppm_mmap(struct file *filp, struct vm_area_struct *vma); static int record_event_consumer(struct ppm_consumer_t *consumer, @@ -206,7 +207,7 @@ static const struct file_operations g_ppm_fops = { */ LIST_HEAD(g_consumer_list); static DEFINE_MUTEX(g_consumer_mutex); -static uint32_t g_tracepoints_attached; // list of attached tracepoints; bitmask using ppm_tp.h enum +static u32 g_tracepoints_attached; // list of attached tracepoints; bitmask using ppm_tp.h enum #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) static struct tracepoint *tp_sys_enter; @@ -347,6 +348,7 @@ static void check_remove_consumer(struct ppm_consumer_t *consumer, int remove_fr static int ppm_open(struct inode *inode, struct file *filp) { int ret; + u32 val; int in_list = false; #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) int ring_no = iminor(filp->f_path.dentry->d_inode); @@ -496,172 +498,28 @@ static int ppm_open(struct inode *inode, struct file *filp) if (g_tracepoints_attached == 0) { pr_info("starting capture\n"); + /* * Enable the tracepoints */ - - /* - * SYS_EXIT - */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - ret = compat_register_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); -#else - ret = register_trace_syscall_exit(syscall_exit_probe); -#endif - if(ret) - { - pr_err("can't create the sys_exit tracepoint\n"); - goto err_sys_exit; - } - g_tracepoints_attached |= 1 << SYS_EXIT; - - /* - * SYS_ENTER - */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - ret = compat_register_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); -#else - ret = register_trace_syscall_enter(syscall_enter_probe); -#endif - if(ret) - { - pr_err("can't create the sys_enter tracepoint\n"); - goto err_sys_enter; - } - g_tracepoints_attached |= 1 << SYS_ENTER; - - /* - * SCHED_PROCESS_EXIT - */ - ret = compat_register_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); - if(ret) + val = (1 << TP_VAL_MAX) - 1; + ret = force_tp_set(val, TP_VAL_MAX); + if (ret != 0) { - pr_err("can't create the sched_process_exit tracepoint\n"); - goto err_sched_procexit; + goto err_tp_set; } - g_tracepoints_attached |= 1 << SCHED_PROC_EXIT; - - /* - * CAPTURE_CONTEXT_SWITCHES - */ -#ifdef CAPTURE_CONTEXT_SWITCHES - ret = compat_register_trace(sched_switch_probe, "sched_switch", tp_sched_switch); - if(ret) - { - pr_err("can't create the sched_switch tracepoint\n"); - goto err_sched_switch; - } - g_tracepoints_attached |= 1 << SCHED_SWITCH; -#endif - - /* - * CAPTURE_SIGNAL_DELIVERIES - */ -#ifdef CAPTURE_SIGNAL_DELIVERIES - ret = compat_register_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - if(ret) - { - pr_err("can't create the signal_deliver tracepoint\n"); - goto err_signal_deliver; - } - g_tracepoints_attached |= 1 << SIGNAL_DELIVER; -#endif - - /* - * CAPTURE_SCHED_PROC_EXEC - */ -#ifdef CAPTURE_SCHED_PROC_EXEC - ret = compat_register_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); - if(ret) - { - pr_err("can't create the 'sched_proc_exec' tracepoint\n"); - goto err_sched_proc_exec; - } - g_tracepoints_attached |= 1 << SCHED_PROC_EXEC; -#endif - - /* - * CAPTURE_SCHED_PROC_FORK - */ -#ifdef CAPTURE_SCHED_PROC_FORK - ret = compat_register_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); - if(ret) - { - pr_err("can't create the 'sched_proc_fork' tracepoint\n"); - goto err_sched_proc_fork; - } - g_tracepoints_attached |= 1 << SCHED_PROC_FORK; -#endif } ret = 0; - goto cleanup_open; - /* - * CAPTURE_SCHED_PROC_FORK - */ -#ifdef CAPTURE_SCHED_PROC_FORK -err_sched_proc_fork: -#endif - - /* - * CAPTURE_SCHED_PROC_EXEC - */ -#ifdef CAPTURE_SCHED_PROC_EXEC - compat_unregister_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); -err_sched_proc_exec: -#endif - - /* - * CAPTURE_SIGNAL_DELIVERIES - */ -#ifdef CAPTURE_SIGNAL_DELIVERIES - compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); -err_signal_deliver: -#endif - - /* - * CAPTURE_CONTEXT_SWITCHES - */ -#ifdef CAPTURE_CONTEXT_SWITCHES - compat_unregister_trace(sched_switch_probe, "sched_switch", tp_sched_switch); -err_sched_switch: -#endif - - /* - * SCHED_PROCESS_EXIT - */ - compat_unregister_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); -err_sched_procexit: - - /* - * SYS_ENTER - */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); -#else - unregister_trace_syscall_enter(syscall_enter_probe); -#endif -err_sys_enter: - - /* - * SYS_EXIT - */ -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); -#else - unregister_trace_syscall_exit(syscall_exit_probe); -#endif - g_tracepoints_attached = 0; -err_sys_exit: - +err_tp_set: ring->open = false; -err_init_ring_buffer: +err_init_ring_buffer: check_remove_consumer(consumer, in_list); -cleanup_open: +cleanup_open: mutex_unlock(&g_consumer_mutex); return ret; @@ -736,93 +594,7 @@ static int ppm_release(struct inode *inode, struct file *filp) if (g_tracepoints_attached != 0) { pr_info("no more consumers, stopping capture\n"); - /* - * SYS_EXIT - */ - if ((g_tracepoints_attached & (1 << SYS_EXIT))) - { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); -#else - unregister_trace_syscall_exit(syscall_exit_probe); -#endif - } - - /* - * SYS_ENTER - */ - if ((g_tracepoints_attached & (1 << SYS_ENTER))) - { -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); -#else - unregister_trace_syscall_enter(syscall_enter_probe); -#endif - } - - /* - * SCHED_PROCESS_EXIT - */ - if ((g_tracepoints_attached & (1 << SCHED_PROC_EXIT))) - { - compat_unregister_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); - } - - /* - * CAPTURE_CONTEXT_SWITCHES - */ -#ifdef CAPTURE_CONTEXT_SWITCHES - if ((g_tracepoints_attached & (1 << SCHED_SWITCH))) - { - compat_unregister_trace(sched_switch_probe, "sched_switch", tp_sched_switch); - } -#endif - - /* - * CAPTURE_SIGNAL_DELIVERIES - */ - -#ifdef CAPTURE_SIGNAL_DELIVERIES - if ((g_tracepoints_attached & (1 << SIGNAL_DELIVER))) - { - compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - } -#endif - - /* - * CAPTURE_PAGE_FAULTS - */ -#ifdef CAPTURE_PAGE_FAULTS - if (g_tracepoints_attached & (1 << PAGE_FAULT_USER)) - { - compat_unregister_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); - } - if (g_tracepoints_attached & (1 << PAGE_FAULT_KERN)) - { - compat_unregister_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); - } -#endif - - /* - * CAPTURE_SCHED_PROC_EXEC - */ -#ifdef CAPTURE_SCHED_PROC_EXEC - if (g_tracepoints_attached & (1 << SCHED_PROC_EXEC)) - { - compat_unregister_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); - } -#endif - - /* - * CAPTURE_SCHED_PROC_FORK - */ -#ifdef CAPTURE_SCHED_PROC_FORK - if (g_tracepoints_attached & (1 << SCHED_PROC_FORK)) - { - compat_unregister_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); - } -#endif - + force_tp_set(0, TP_VAL_MAX); #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) tracepoint_synchronize_unregister(); #endif @@ -847,12 +619,34 @@ static int ppm_release(struct inode *inode, struct file *filp) return ret; } -static int force_tp_set(int new_tp_set) +static int compat_set_tracepoint(void *func, const char *probename, struct tracepoint *tp, bool enabled) +{ + int ret = 0; + if (enabled) + { + ret = compat_register_trace(func, probename, tp); + } + else + { + compat_unregister_trace(func, probename, tp); + } + return ret; +} + +static int force_tp_set(u32 new_tp_set, u32 max_val) { u32 idx; u32 new_val; u32 curr_val; - for(idx = 0; idx < TP_VAL_MAX; idx++) + int ret = 0; + + if (new_tp_set == g_tracepoints_attached) + { + // ok already equal + return ret; + } + + for(idx = 0; idx < max_val && ret == 0; idx++) { new_val = new_tp_set & (1 << idx); curr_val = g_tracepoints_attached & (1 << idx); @@ -861,15 +655,16 @@ static int force_tp_set(int new_tp_set) // no change needed continue; } + switch(idx) { case SYS_ENTER: if(new_val) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_register_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); + ret = compat_register_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); #else - register_trace_syscall_enter(syscall_enter_probe); + ret = register_trace_syscall_enter(syscall_enter_probe); #endif } else @@ -885,9 +680,9 @@ static int force_tp_set(int new_tp_set) if(new_val) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_register_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); + ret = compat_register_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); #else - register_trace_syscall_exit(syscall_exit_probe); + ret = register_trace_syscall_exit(syscall_exit_probe); #endif } else @@ -900,98 +695,75 @@ static int force_tp_set(int new_tp_set) } break; case SCHED_PROC_EXIT: - if (new_val) - { - compat_register_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); - } - else - { - compat_unregister_trace(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit); - } + ret = compat_set_tracepoint(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit, new_val); break; #ifdef CAPTURE_CONTEXT_SWITCHES case SCHED_SWITCH: - if (new_val) - { - compat_register_trace(sched_switch_probe, "sched_switch", tp_sched_switch); - } - else - { - compat_unregister_trace(sched_switch_probe, "sched_switch", tp_sched_switch); - } + ret = compat_set_tracepoint(sched_switch_probe, "sched_switch", tp_sched_switch, new_val); break; #endif #ifdef CAPTURE_PAGE_FAULTS case PAGE_FAULT_USER: - if (new_val) + if (!g_fault_tracepoint_disabled) { - compat_register_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); - } - else - { - compat_unregister_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); + ret = compat_set_tracepoint(page_fault_probe, "page_fault_user", tp_page_fault_user, new_val); } break; case PAGE_FAULT_KERN: - if (new_val) + if (!g_fault_tracepoint_disabled) { - compat_register_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); - } - else - { - compat_unregister_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); + ret = compat_set_tracepoint(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel, new_val); } break; #endif #ifdef CAPTURE_SIGNAL_DELIVERIES case SIGNAL_DELIVER: - if (new_val) - { - compat_register_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - } - else - { - compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - } + ret = compat_set_tracepoint(signal_deliver_probe, "signal_deliver", tp_signal_deliver, new_val); break; #endif #ifdef CAPTURE_SCHED_PROC_FORK case SCHED_PROC_FORK: - if (new_val) - { - compat_register_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); - } - else - { - compat_unregister_trace(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork); - } + ret = compat_set_tracepoint(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork, new_val); break; #endif #ifdef CAPTURE_SCHED_PROC_EXEC case SCHED_PROC_EXEC: - if (new_val) - { - compat_register_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); - } - else - { - compat_unregister_trace(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec); - } + ret = compat_set_tracepoint(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec, new_val); break; #endif default: // unmanaged idx break; } + + if (new_val) + { + if (ret == 0) + { + g_tracepoints_attached |= 1 << idx; + } + else + { + pr_err("can't create the %s tracepoint\n", tp_names[idx]); + } + } + } + + if (ret != 0) + { + // Error: reset first idx-1 bits to 0. + // This means that we are requesting to unregister first + // idx-1 tracepoints, that are the succedeed ones before the error. + force_tp_set(0, idx - 1); } - g_tracepoints_attached = new_tp_set; - return 0; // TODO error handling + return ret; } static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int cpu; int ret; + u32 new_tp_set; struct task_struct *consumer_id = filp->private_data; struct ppm_consumer_t *consumer = NULL; @@ -1403,18 +1175,16 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) #ifdef CAPTURE_SIGNAL_DELIVERIES case PPM_IOCTL_DISABLE_SIGNAL_DELIVER: { + new_tp_set = g_tracepoints_attached & ~(1 << SIGNAL_DELIVER); vpr_info("PPM_IOCTL_DISABLE_SIGNAL_DELIVER\n"); - if (g_tracepoints_attached & (1 << SIGNAL_DELIVER)) - compat_unregister_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - ret = 0; + ret = force_tp_set(new_tp_set, TP_VAL_MAX); goto cleanup_ioctl; } case PPM_IOCTL_ENABLE_SIGNAL_DELIVER: { + new_tp_set = g_tracepoints_attached | (1 << SIGNAL_DELIVER); vpr_info("PPM_IOCTL_ENABLE_SIGNAL_DELIVER\n"); - if (!(g_tracepoints_attached & (1 << SIGNAL_DELIVER))) - compat_register_trace(signal_deliver_probe, "signal_deliver", tp_signal_deliver); - ret = 0; + ret = force_tp_set(new_tp_set, TP_VAL_MAX); goto cleanup_ioctl; } #endif @@ -1437,31 +1207,8 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto cleanup_ioctl; } - if (!(g_tracepoints_attached & (1 << PAGE_FAULT_USER))) - { - ret = compat_register_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); - if(ret) - { - pr_err("can't create the page_fault_user tracepoint\n"); - ret = -EINVAL; - goto cleanup_ioctl; - } - g_tracepoints_attached |= 1 << PAGE_FAULT_USER; - } - - if (!(g_tracepoints_attached & (1 << PAGE_FAULT_KERN))) - { - ret = compat_register_trace(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel); - if(ret) - { - pr_err("can't create the page_fault_kernel tracepoint\n"); - ret = -EINVAL; - goto err_page_fault_kernel; - } - g_tracepoints_attached |= 1 << PAGE_FAULT_KERN; - } - - ret = 0; + new_tp_set = g_tracepoints_attached | (1 << PAGE_FAULT_USER) | (1 << PAGE_FAULT_KERN); + ret = force_tp_set(new_tp_set, TP_VAL_MAX); goto cleanup_ioctl; #else pr_err("kernel doesn't support page fault tracepoints\n"); @@ -1471,7 +1218,7 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } case PPM_IOCTL_MANAGE_TP: { - ret = force_tp_set( (u32)arg); + ret = force_tp_set((u32)arg, TP_VAL_MAX); goto cleanup_ioctl; } default: @@ -1479,11 +1226,6 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto cleanup_ioctl; } -#ifdef CAPTURE_PAGE_FAULTS -err_page_fault_kernel: - compat_unregister_trace(page_fault_probe, "page_fault_user", tp_page_fault_user); - g_tracepoints_attached &= ~(1 << PAGE_FAULT_USER); -#endif cleanup_ioctl: mutex_unlock(&g_consumer_mutex); cleanup_ioctl_nolock: diff --git a/driver/ppm_tp.h b/driver/ppm_tp.h index 8f7145884b..978461cddf 100644 --- a/driver/ppm_tp.h +++ b/driver/ppm_tp.h @@ -17,4 +17,6 @@ typedef enum { TP_FIELDS #undef X TP_VAL_MAX, -} tp_values; \ No newline at end of file +} tp_values; + +extern const char *tp_names[]; \ No newline at end of file diff --git a/driver/tp_table.c b/driver/tp_table.c new file mode 100644 index 0000000000..9094b67323 --- /dev/null +++ b/driver/tp_table.c @@ -0,0 +1,7 @@ +#include "ppm_tp.h" + +const char *tp_names[] = { +#define X(name, path) path, + TP_FIELDS +#undef X +}; \ No newline at end of file diff --git a/userspace/libscap/CMakeLists.txt b/userspace/libscap/CMakeLists.txt index 2594345d9a..ed9a48d460 100644 --- a/userspace/libscap/CMakeLists.txt +++ b/userspace/libscap/CMakeLists.txt @@ -162,7 +162,8 @@ target_link_libraries(scap scap_event_schema) if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_library(driver_event_schema ../../driver/syscall_table.c - ../../driver/fillers_table.c) + ../../driver/fillers_table.c + ../../driver/tp_table.c) target_link_libraries(scap_event_schema driver_event_schema) endif() diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 1c0b43f60f..d3ef9a80f3 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -646,12 +646,6 @@ static int32_t load_tracepoint(struct bpf_engine* handle, const char *event, str static tp_values tp_from_name(const char *tp_path) { - static const char *names[] = { -#define X(name, path) path, - TP_FIELDS -#undef X - }; - // Find last '/' occurrence to take only the basename const char *tp_name = strrchr(tp_path, '/'); if (tp_name && strlen(tp_name) > 1) @@ -659,7 +653,7 @@ static tp_values tp_from_name(const char *tp_path) tp_name++; for (int i = 0; i < TP_VAL_MAX; i++) { - if (strcmp(tp_name, names[i]) == 0) + if (strcmp(tp_name, tp_names[i]) == 0) { return i; } @@ -1021,7 +1015,6 @@ static int32_t calibrate_socket_file_ops() int32_t scap_bpf_start_capture(struct scap_engine_handle engine) { struct bpf_engine* handle = engine.m_handle; - struct scap_bpf_settings settings; int k = 0; diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 651af1c004..fd66bc38c8 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -63,16 +63,10 @@ char* valptr = NULL; /* pointer used to print the value of event params. * void enable_single_tp(const char *tp_basename) { - static const char *names[] = { -#define X(name, tp_path) tp_path, - TP_FIELDS -#undef X - }; - bool found = false; for (int i = 0; i < TP_VAL_MAX && !found; i++) { - if (strcmp(names[i], tp_basename) == 0) + if (strcmp(tp_names[i], tp_basename) == 0) { tp_of_interest.tp[i] = true; found = true; @@ -84,7 +78,7 @@ void enable_single_tp(const char *tp_basename) fprintf(stderr, "Please choose between:\n"); for (int i = 0; i < TP_VAL_MAX; i++) { - fprintf(stderr, "\t* %s\n", names[i]); + fprintf(stderr, "\t* %s\n", tp_names[i]); } exit(EXIT_FAILURE); } diff --git a/userspace/libsinsp/event.cpp b/userspace/libsinsp/event.cpp index dbdb0ca5b1..57f4c5d095 100644 --- a/userspace/libsinsp/event.cpp +++ b/userspace/libsinsp/event.cpp @@ -2668,7 +2668,7 @@ scap_dump_flags sinsp_evt::get_dump_flags(OUT bool* should_drop) return (scap_dump_flags)dflags; } -bool sinsp_evt::simple_consumer_consider() +bool sinsp_evt::should_consider() { uint16_t etype = get_type(); @@ -2678,10 +2678,10 @@ bool sinsp_evt::simple_consumer_consider() ASSERT(parinfo->m_len == sizeof(uint16_t)); uint16_t scid = *(uint16_t *)parinfo->m_val; - return sinsp::simple_consumer_consider_syscallid(scid); + return sinsp::should_consider_syscallid(scid); } - return sinsp::simple_consumer_consider_evtnum(etype); + return sinsp::should_consider_evtnum(etype); } bool sinsp_evt::is_syscall_error() const diff --git a/userspace/libsinsp/event.h b/userspace/libsinsp/event.h index c666cd30fc..da8f08d61d 100644 --- a/userspace/libsinsp/event.h +++ b/userspace/libsinsp/event.h @@ -341,13 +341,12 @@ class SINSP_PUBLIC sinsp_evt : public gen_event scap_dump_flags get_dump_flags(OUT bool* should_drop); /*! - \brief Return whether or not a simple consumer that privileges low overhead to - full event capture should consider this event. (Generally, these events are + \brief Return whether or not an event should be considered. (Generally, these events are automatically filtered out, but some events related to internal tracking are returned by next() anyway). */ - bool simple_consumer_consider(); + bool should_consider(); inline uint16_t get_source() const override { diff --git a/userspace/libsinsp/fields_info.cpp b/userspace/libsinsp/fields_info.cpp index 554a7f4393..12a6e0beac 100644 --- a/userspace/libsinsp/fields_info.cpp +++ b/userspace/libsinsp/fields_info.cpp @@ -96,7 +96,7 @@ void list_events(sinsp* inspector, bool markdown) if(markdown) { - if(sinsp::simple_consumer_consider_evtnum(j)) + if(sinsp::should_consider_evtnum(j)) { printf("Yes"); } else { diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 2db1a84556..35846caa72 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -480,7 +480,6 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) else { m_ppm_sc_of_interest.erase(ppm_sc); - } } diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 2dfb7dc3fe..d314a14e99 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -891,18 +891,18 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source } #endif - static inline bool simple_consumer_consider_evtnum(uint16_t etype) + static inline bool should_consider_evtnum(uint16_t etype) { enum ppm_event_flags flags = g_infotables.m_event_info[etype].flags; - return ! (flags & sinsp::simple_consumer_skip_flags()); + return ! (flags & sinsp::event_skip_flags()); } - static inline bool simple_consumer_consider_syscallid(uint16_t scid) + static inline bool should_consider_syscallid(uint16_t scid) { enum ppm_event_flags flags = g_infotables.m_syscall_info_table[scid].flags; - return ! (flags & sinsp::simple_consumer_skip_flags()); + return ! (flags & sinsp::event_skip_flags()); } // Add comm to the list of comms for which the inspector @@ -953,7 +953,7 @@ VISIBILITY_PROTECTED VISIBILITY_PRIVATE - static inline ppm_event_flags simple_consumer_skip_flags() + static inline ppm_event_flags event_skip_flags() { return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED | EF_OLD_VERSION); } From 1b89ed5f332096421c43018aea4c8141d0afc5dd Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 4 Aug 2022 10:23:08 +0200 Subject: [PATCH 04/29] chore(driver): restore old behavior in ppm_open: do not automatically register page fault tracepoints. Moreover, use tp_names variable instead of static storage strings. Signed-off-by: Federico Di Pierro --- driver/main.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/driver/main.c b/driver/main.c index 2e10ab6848..58f4895088 100644 --- a/driver/main.c +++ b/driver/main.c @@ -500,9 +500,12 @@ static int ppm_open(struct inode *inode, struct file *filp) pr_info("starting capture\n"); /* - * Enable the tracepoints + * Enable the tracepoints, excepts for page faults + * that are enabled through PPM_IOCTL_ENABLE_PAGE_FAULTS */ val = (1 << TP_VAL_MAX) - 1; + val &= ~(1 << PAGE_FAULT_USER); + val &= ~(1 << PAGE_FAULT_KERN); ret = force_tp_set(val, TP_VAL_MAX); if (ret != 0) { @@ -662,7 +665,7 @@ static int force_tp_set(u32 new_tp_set, u32 max_val) if(new_val) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - ret = compat_register_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); + ret = compat_register_trace(syscall_enter_probe, tp_names[idx], tp_sys_enter); #else ret = register_trace_syscall_enter(syscall_enter_probe); #endif @@ -670,7 +673,7 @@ static int force_tp_set(u32 new_tp_set, u32 max_val) else { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_enter_probe, "sys_enter", tp_sys_enter); + compat_unregister_trace(syscall_enter_probe, tp_names[idx], tp_sys_enter); #else unregister_trace_syscall_enter(syscall_enter_probe); #endif @@ -680,7 +683,7 @@ static int force_tp_set(u32 new_tp_set, u32 max_val) if(new_val) { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - ret = compat_register_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); + ret = compat_register_trace(syscall_exit_probe, tp_names[idx], tp_sys_exit); #else ret = register_trace_syscall_exit(syscall_exit_probe); #endif @@ -688,47 +691,47 @@ static int force_tp_set(u32 new_tp_set, u32 max_val) else { #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - compat_unregister_trace(syscall_exit_probe, "sys_exit", tp_sys_exit); + compat_unregister_trace(syscall_exit_probe, tp_names[idx], tp_sys_exit); #else unregister_trace_syscall_exit(syscall_exit_probe); #endif } break; case SCHED_PROC_EXIT: - ret = compat_set_tracepoint(syscall_procexit_probe, "sched_process_exit", tp_sched_process_exit, new_val); + ret = compat_set_tracepoint(syscall_procexit_probe, tp_names[idx], tp_sched_process_exit, new_val); break; #ifdef CAPTURE_CONTEXT_SWITCHES case SCHED_SWITCH: - ret = compat_set_tracepoint(sched_switch_probe, "sched_switch", tp_sched_switch, new_val); + ret = compat_set_tracepoint(sched_switch_probe, tp_names[idx], tp_sched_switch, new_val); break; #endif #ifdef CAPTURE_PAGE_FAULTS case PAGE_FAULT_USER: if (!g_fault_tracepoint_disabled) { - ret = compat_set_tracepoint(page_fault_probe, "page_fault_user", tp_page_fault_user, new_val); + ret = compat_set_tracepoint(page_fault_probe, tp_names[idx], tp_page_fault_user, new_val); } break; case PAGE_FAULT_KERN: if (!g_fault_tracepoint_disabled) { - ret = compat_set_tracepoint(page_fault_probe, "page_fault_kernel", tp_page_fault_kernel, new_val); + ret = compat_set_tracepoint(page_fault_probe, tp_names[idx], tp_page_fault_kernel, new_val); } break; #endif #ifdef CAPTURE_SIGNAL_DELIVERIES case SIGNAL_DELIVER: - ret = compat_set_tracepoint(signal_deliver_probe, "signal_deliver", tp_signal_deliver, new_val); + ret = compat_set_tracepoint(signal_deliver_probe, tp_names[idx], tp_signal_deliver, new_val); break; #endif #ifdef CAPTURE_SCHED_PROC_FORK case SCHED_PROC_FORK: - ret = compat_set_tracepoint(sched_proc_fork_probe, "sched_process_fork", tp_sched_proc_fork, new_val); + ret = compat_set_tracepoint(sched_proc_fork_probe, tp_names[idx], tp_sched_proc_fork, new_val); break; #endif #ifdef CAPTURE_SCHED_PROC_EXEC case SCHED_PROC_EXEC: - ret = compat_set_tracepoint(sched_proc_exec_probe, "sched_process_exec", tp_sched_proc_exec, new_val); + ret = compat_set_tracepoint(sched_proc_exec_probe, tp_names[idx], tp_sched_proc_exec, new_val); break; #endif default: @@ -2577,37 +2580,37 @@ static void reset_ring_buffer(struct ppm_ring_buffer_context *ring) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) static void visit_tracepoint(struct tracepoint *tp, void *priv) { - if (!strcmp(tp->name, "sys_enter")) + if (!strcmp(tp->name, tp_names[SYS_ENTER])) tp_sys_enter = tp; - else if (!strcmp(tp->name, "sys_exit")) + else if (!strcmp(tp->name, tp_names[SYS_EXIT])) tp_sys_exit = tp; - else if (!strcmp(tp->name, "sched_process_exit")) + else if (!strcmp(tp->name, tp_names[SCHED_PROC_EXIT])) tp_sched_process_exit = tp; #ifdef CAPTURE_CONTEXT_SWITCHES - else if (!strcmp(tp->name, "sched_switch")) + else if (!strcmp(tp->name, tp_names[SCHED_SWITCH])) tp_sched_switch = tp; #endif #ifdef CAPTURE_SIGNAL_DELIVERIES - else if (!strcmp(tp->name, "signal_deliver")) + else if (!strcmp(tp->name, tp_names[SIGNAL_DELIVER])) tp_signal_deliver = tp; #endif #ifdef CAPTURE_PAGE_FAULTS - else if (!strcmp(tp->name, "page_fault_user")) + else if (!strcmp(tp->name, tp_names[PAGE_FAULT_USER])) tp_page_fault_user = tp; - else if (!strcmp(tp->name, "page_fault_kernel")) + else if (!strcmp(tp->name, tp_names[PAGE_FAULT_KERN])) tp_page_fault_kernel = tp; #endif #ifdef CAPTURE_SCHED_PROC_EXEC - else if (!strcmp(tp->name, "sched_process_exec")) + else if (!strcmp(tp->name, tp_names[SCHED_PROC_EXEC])) tp_sched_proc_exec = tp; #endif #ifdef CAPTURE_SCHED_PROC_FORK - else if (!strcmp(tp->name, "sched_process_fork")) + else if (!strcmp(tp->name, tp_names[SCHED_PROC_FORK])) tp_sched_proc_fork = tp; #endif } From 046001c0f401930113fb76d0a1400791e57ddcf9 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 4 Aug 2022 11:16:01 +0200 Subject: [PATCH 05/29] cleanup(driver,userspace/libscap,userspace/libsinsp): completely drop runtime page fault and signal deliver ioctl for kmod. Signal deliver where unused; page fault was only used by some consumers by enabling it at startup time. Now, consumers can use new scap_open_args tp_of_interest feature instead, that is now exposed through libsinsp too. We expect Falco to be updated setting both syscalls_of_interest and tp_of_interest in default mode (ex simple consumer mode) and in '-A' (all syscalls) mode. Signed-off-by: Federico Di Pierro Co-authored-by: Andrea Terzolo --- driver/bpf/probe.c | 3 -- driver/bpf/types.h | 1 - driver/main.c | 43 +-------------------- driver/ppm_events_public.h | 6 +-- driver/ppm_tp.h | 3 +- driver/tp_table.c | 23 ++++++++++- userspace/libscap/engine/bpf/scap_bpf.c | 47 ----------------------- userspace/libscap/engine/kmod/scap_kmod.c | 24 ------------ userspace/libscap/engine/udig/scap_udig.c | 8 ---- userspace/libscap/scap.c | 16 -------- userspace/libscap/scap.h | 1 - userspace/libscap/scap_vtable.h | 5 --- userspace/libsinsp/sinsp.cpp | 41 +++++++++++++------- userspace/libsinsp/sinsp.h | 10 +++-- 14 files changed, 63 insertions(+), 168 deletions(-) diff --git a/driver/bpf/probe.c b/driver/bpf/probe.c index 91bea0685b..1bc7130914 100644 --- a/driver/bpf/probe.c +++ b/driver/bpf/probe.c @@ -188,9 +188,6 @@ static __always_inline int bpf_page_fault(struct page_fault_args *ctx) if (!settings) return 0; - if (!settings->page_faults) - return 0; - if (!settings->capture_enabled) return 0; diff --git a/driver/bpf/types.h b/driver/bpf/types.h index ea5c827e8f..52d9d18884 100644 --- a/driver/bpf/types.h +++ b/driver/bpf/types.h @@ -233,7 +233,6 @@ struct scap_bpf_settings { uint32_t sampling_ratio; bool capture_enabled; bool do_dynamic_snaplen; - bool page_faults; bool dropping_mode; bool is_dropping; bool tracers_enabled; diff --git a/driver/main.c b/driver/main.c index 58f4895088..688a8076ca 100644 --- a/driver/main.c +++ b/driver/main.c @@ -500,12 +500,9 @@ static int ppm_open(struct inode *inode, struct file *filp) pr_info("starting capture\n"); /* - * Enable the tracepoints, excepts for page faults - * that are enabled through PPM_IOCTL_ENABLE_PAGE_FAULTS + * Enable the tracepoints */ val = (1 << TP_VAL_MAX) - 1; - val &= ~(1 << PAGE_FAULT_USER); - val &= ~(1 << PAGE_FAULT_KERN); ret = force_tp_set(val, TP_VAL_MAX); if (ret != 0) { @@ -766,7 +763,6 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int cpu; int ret; - u32 new_tp_set; struct task_struct *consumer_id = filp->private_data; struct ppm_consumer_t *consumer = NULL; @@ -1175,22 +1171,6 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = task_tgid_nr(current); goto cleanup_ioctl; #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) */ -#ifdef CAPTURE_SIGNAL_DELIVERIES - case PPM_IOCTL_DISABLE_SIGNAL_DELIVER: - { - new_tp_set = g_tracepoints_attached & ~(1 << SIGNAL_DELIVER); - vpr_info("PPM_IOCTL_DISABLE_SIGNAL_DELIVER\n"); - ret = force_tp_set(new_tp_set, TP_VAL_MAX); - goto cleanup_ioctl; - } - case PPM_IOCTL_ENABLE_SIGNAL_DELIVER: - { - new_tp_set = g_tracepoints_attached | (1 << SIGNAL_DELIVER); - vpr_info("PPM_IOCTL_ENABLE_SIGNAL_DELIVER\n"); - ret = force_tp_set(new_tp_set, TP_VAL_MAX); - goto cleanup_ioctl; - } -#endif case PPM_IOCTL_SET_TRACERS_CAPTURE: { vpr_info("PPM_IOCTL_SET_TRACERS_CAPTURE, consumer %p\n", consumer_id); @@ -1198,27 +1178,6 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = 0; goto cleanup_ioctl; } - case PPM_IOCTL_ENABLE_PAGE_FAULTS: - { - vpr_info("PPM_IOCTL_ENABLE_PAGE_FAULTS\n"); -#ifdef CAPTURE_PAGE_FAULTS - ASSERT(g_tracepoint_attached > 0); - - if (g_fault_tracepoint_disabled) { - pr_err("kernel page fault tracepoints are disabled\n"); - ret = -EPERM; - goto cleanup_ioctl; - } - - new_tp_set = g_tracepoints_attached | (1 << PAGE_FAULT_USER) | (1 << PAGE_FAULT_KERN); - ret = force_tp_set(new_tp_set, TP_VAL_MAX); - goto cleanup_ioctl; -#else - pr_err("kernel doesn't support page fault tracepoints\n"); - ret = -EINVAL; - goto cleanup_ioctl; -#endif - } case PPM_IOCTL_MANAGE_TP: { ret = force_tp_set((u32)arg, TP_VAL_MAX); diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index 8a0a99ff1b..e56522a091 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -1706,12 +1706,12 @@ struct ppm_evt_hdr { #define PPM_IOCTL_GET_VPID _IO(PPM_IOCTL_MAGIC, 11) #define PPM_IOCTL_GET_CURRENT_TID _IO(PPM_IOCTL_MAGIC, 12) #define PPM_IOCTL_GET_CURRENT_PID _IO(PPM_IOCTL_MAGIC, 13) -#define PPM_IOCTL_DISABLE_SIGNAL_DELIVER _IO(PPM_IOCTL_MAGIC, 14) -#define PPM_IOCTL_ENABLE_SIGNAL_DELIVER _IO(PPM_IOCTL_MAGIC, 15) +// #define PPM_IOCTL_DISABLE_SIGNAL_DELIVER _IO(PPM_IOCTL_MAGIC, 14) Support dropped +// #define PPM_IOCTL_ENABLE_SIGNAL_DELIVER _IO(PPM_IOCTL_MAGIC, 15) Support dropped #define PPM_IOCTL_GET_PROCLIST _IO(PPM_IOCTL_MAGIC, 16) #define PPM_IOCTL_SET_TRACERS_CAPTURE _IO(PPM_IOCTL_MAGIC, 17) // #define PPM_IOCTL_SET_SIMPLE_MODE _IO(PPM_IOCTL_MAGIC, 18) Support dropped -#define PPM_IOCTL_ENABLE_PAGE_FAULTS _IO(PPM_IOCTL_MAGIC, 19) +// #define PPM_IOCTL_ENABLE_PAGE_FAULTS _IO(PPM_IOCTL_MAGIC, 19) Support dropped #define PPM_IOCTL_GET_N_TRACEPOINT_HIT _IO(PPM_IOCTL_MAGIC, 20) #define PPM_IOCTL_GET_DRIVER_VERSION _IO(PPM_IOCTL_MAGIC, 21) #define PPM_IOCTL_SET_FULLCAPTURE_PORT_RANGE _IO(PPM_IOCTL_MAGIC, 22) diff --git a/driver/ppm_tp.h b/driver/ppm_tp.h index 978461cddf..0a1ae2608d 100644 --- a/driver/ppm_tp.h +++ b/driver/ppm_tp.h @@ -19,4 +19,5 @@ typedef enum { TP_VAL_MAX, } tp_values; -extern const char *tp_names[]; \ No newline at end of file +extern const char *tp_names[]; +extern tp_values tp_from_name(const char *tp_path); \ No newline at end of file diff --git a/driver/tp_table.c b/driver/tp_table.c index 9094b67323..c7e6edec9e 100644 --- a/driver/tp_table.c +++ b/driver/tp_table.c @@ -4,4 +4,25 @@ const char *tp_names[] = { #define X(name, path) path, TP_FIELDS #undef X -}; \ No newline at end of file +}; + +#ifndef __KERNEL__ +#include +tp_values tp_from_name(const char *tp_path) +{ + // Find last '/' occurrence to take only the basename + const char *tp_name = strrchr(tp_path, '/'); + if (tp_name && strlen(tp_name) > 1) + { + tp_name++; + for (int i = 0; i < TP_VAL_MAX; i++) + { + if (strcmp(tp_name, tp_names[i]) == 0) + { + return i; + } + } + } + return -1; +} +#endif \ No newline at end of file diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index d3ef9a80f3..c815d51b3c 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -644,24 +644,6 @@ static int32_t load_tracepoint(struct bpf_engine* handle, const char *event, str return SCAP_SUCCESS; } -static tp_values tp_from_name(const char *tp_path) -{ - // Find last '/' occurrence to take only the basename - const char *tp_name = strrchr(tp_path, '/'); - if (tp_name && strlen(tp_name) > 1) - { - tp_name++; - for (int i = 0; i < TP_VAL_MAX; i++) - { - if (strcmp(tp_name, tp_names[i]) == 0) - { - return i; - } - } - } - return -1; -} - static bool is_tp_enabled(interesting_tp_set *tp_of_interest, const char *shname) { if (tp_of_interest) @@ -1243,28 +1225,6 @@ int32_t scap_bpf_enable_dynamic_snaplen(struct scap_engine_handle engine) return SCAP_SUCCESS; } -int32_t scap_bpf_enable_page_faults(struct scap_engine_handle engine) -{ - struct scap_bpf_settings settings; - struct bpf_engine *handle = engine.m_handle; - int k = 0; - - if(bpf_map_lookup_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings) != 0) - { - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_lookup_elem < 0"); - return SCAP_FAILURE; - } - - settings.page_faults = true; - if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_SETTINGS_MAP], &k, &settings, BPF_ANY) != 0) - { - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_SETTINGS_MAP bpf_map_update_elem < 0"); - return SCAP_FAILURE; - } - - return SCAP_SUCCESS; -} - int32_t scap_bpf_enable_tracers_capture(struct scap_engine_handle engine) { struct scap_bpf_settings settings; @@ -1442,7 +1402,6 @@ static int32_t set_default_settings(struct bpf_engine *handle) settings.sampling_ratio = 1; settings.capture_enabled = false; settings.do_dynamic_snaplen = false; - settings.page_faults = false; settings.dropping_mode = false; settings.is_dropping = false; settings.tracers_enabled = false; @@ -1744,12 +1703,6 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set return unsupported_config(engine, "Tracers cannot be disabled once enabled"); } return scap_bpf_enable_tracers_capture(engine); - case SCAP_PAGE_FAULTS: - if(arg1 == 0) - { - return unsupported_config(engine, "Page faults cannot be disabled once enabled"); - } - return scap_bpf_enable_page_faults(engine); case SCAP_SNAPLEN: return scap_bpf_set_snaplen(engine, arg1); case SCAP_EVENTMASK: diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index 51cb68281b..17689baed9 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -431,24 +431,6 @@ int32_t scap_kmod_enable_tracers_capture(struct scap_engine_handle engine) return SCAP_SUCCESS; } -int32_t scap_kmod_enable_page_faults(struct scap_engine_handle engine) -{ - struct scap_device_set *devset = &engine.m_handle->m_dev_set; - if(devset->m_ndevs) - { - { - if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_ENABLE_PAGE_FAULTS)) - { - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, "%s failed", __FUNCTION__); - ASSERT(false); - return SCAP_FAILURE; - } - } - } - - return SCAP_SUCCESS; -} - int32_t scap_kmod_stop_dropping_mode(struct scap_engine_handle engine) { return scap_kmod_set_dropping_mode(engine, PPM_IOCTL_DISABLE_DROPPING_MODE, 0); @@ -681,12 +663,6 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set return unsupported_config(engine, "Tracers cannot be disabled once enabled"); } return scap_kmod_enable_tracers_capture(engine); - case SCAP_PAGE_FAULTS: - if(arg1 == 0) - { - return unsupported_config(engine, "Page faults cannot be disabled once enabled"); - } - return scap_kmod_enable_page_faults(engine); case SCAP_SNAPLEN: return scap_kmod_set_snaplen(engine, arg1); case SCAP_EVENTMASK: diff --git a/userspace/libscap/engine/udig/scap_udig.c b/userspace/libscap/engine/udig/scap_udig.c index 35ce75c5b0..0b12fa5717 100644 --- a/userspace/libscap/engine/udig/scap_udig.c +++ b/userspace/libscap/engine/udig/scap_udig.c @@ -822,14 +822,6 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set } // yes, it's a no-op in udig return SCAP_SUCCESS; - case SCAP_PAGE_FAULTS: - if(arg1 == 0) - { - return unsupported_config(engine, "Page faults cannot be disabled once enabled"); - } - // the original code blindly tries a kmod-only ioctl - // which can only fail. Let's return a better error code instead - return SCAP_NOT_SUPPORTED; case SCAP_SNAPLEN: return udig_set_snaplen(engine, arg1); case SCAP_EVENTMASK: diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 4d1c9c00f0..4326f7479b 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1236,22 +1236,6 @@ int32_t scap_enable_tracers_capture(scap_t* handle) #endif } -int32_t scap_enable_page_faults(scap_t *handle) -{ - if(handle->m_vtable) - { - return handle->m_vtable->configure(handle->m_engine, SCAP_PAGE_FAULTS, 1, 0); - } -#if defined(HAS_CAPTURE) && ! defined(CYGWING_AGENT) && ! defined(_WIN32) - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "scap_enable_page_faults not supported on this scap mode"); - ASSERT(false); - return SCAP_FAILURE; -#else - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "scap_enable_page_faults not supported on %s", PLATFORM_NAME); - return SCAP_FAILURE; -#endif -} - int32_t scap_stop_dropping_mode(scap_t* handle) { if(handle->m_vtable) diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 4b91af19a8..720aea87e3 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -1068,7 +1068,6 @@ void scap_set_refresh_proc_table_when_saving(scap_t* handle, bool refresh); uint64_t scap_ftell(scap_t *handle); void scap_fseek(scap_t *handle, uint64_t off); int32_t scap_enable_tracers_capture(scap_t* handle); -int32_t scap_enable_page_faults(scap_t *handle); int32_t scap_proc_add(scap_t* handle, uint64_t tid, scap_threadinfo* tinfo); int32_t scap_fd_add(scap_t *handle, scap_threadinfo* tinfo, uint64_t fd, scap_fdinfo* fdinfo); scap_dumper_t *scap_memory_dump_open(scap_t *handle, uint8_t* targetbuf, uint64_t targetbufsize); diff --git a/userspace/libscap/scap_vtable.h b/userspace/libscap/scap_vtable.h index 3425c67f5a..10c3035395 100644 --- a/userspace/libscap/scap_vtable.h +++ b/userspace/libscap/scap_vtable.h @@ -58,11 +58,6 @@ enum scap_setting { * arg1: enabled? */ SCAP_TRACERS_CAPTURE, - /** - * @brief instrument page faults - * arg1: enabled? - */ - SCAP_PAGE_FAULTS, /** * @brief length of captured data buffers * arg1: the length (< 65536) diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 35846caa72..9c9874738f 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -74,6 +74,7 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str m_container_manager(this, static_container, static_id, static_name, static_image), m_usergroup_manager(this), m_ppm_sc_of_interest(), + m_ppm_tp_of_interest(), m_suppressed_comms(), m_inited(false) { @@ -258,19 +259,6 @@ void sinsp::enable_tracers_capture() #endif } -void sinsp::enable_page_faults() -{ -#if defined(HAS_CAPTURE) && ! defined(CYGWING_AGENT) && ! defined(_WIN32) - if(is_live() && m_h != NULL) - { - if(scap_enable_page_faults(m_h) != SCAP_SUCCESS) - { - throw sinsp_exception("error enabling page_faults"); - } - } -#endif -} - bool sinsp::is_initialstate_event(scap_evt* pevent) { return pevent->type == PPME_CONTAINER_E || @@ -466,11 +454,20 @@ void sinsp::set_import_users(bool import_users) m_usergroup_manager.m_import_users = import_users; } +#ifdef __linux__ void sinsp::set_syscalls_of_interest(std::unordered_set &syscalls_of_interest) { m_ppm_sc_of_interest = syscalls_of_interest; } +void sinsp::set_tracepoints_of_interest(std::unordered_set &tp_of_interest) +{ + for (auto tp : tp_of_interest) + { + mark_tracepoint_of_interest(tp, true); + } +} + void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) { if (enabled) @@ -483,6 +480,24 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) } } +void sinsp::mark_tracepoint_of_interest(string &tp, bool enabled) +{ + uint32_t val = (uint32_t)tp_from_name(tp.c_str()); + if (val == -1) + { + throw sinsp_exception("unexisting tracepoint " + tp); + } + + if (enabled) + { + m_ppm_tp_of_interest.insert(val); + } + else + { + m_ppm_tp_of_interest.erase(val); + } +} + void sinsp::fill_syscalls_of_interest(scap_open_args *oargs) { // Fallback to set all events as interesting diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index d314a14e99..c7cf296d3c 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -854,9 +854,13 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source sinsp_parser* get_parser(); + // These make no sense on non-linux env +#ifdef __linux__ void set_syscalls_of_interest(std::unordered_set &syscalls_of_interest); + void set_tracepoints_of_interest(std::unordered_set &tp_of_interest); void mark_syscall_of_interest(uint32_t ppm_sc, bool enabled = true); - + void mark_tracepoint_of_interest(string &tp, bool enabled = true); +#endif bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress); void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo); void add_meta_event(sinsp_evt *metaevt); @@ -864,7 +868,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source void remove_meta_event_callback(); void filter_proc_table_when_saving(bool filter); void enable_tracers_capture(); - void enable_page_faults(); uint64_t get_bytes_read() { return scap_ftell(m_h); @@ -973,6 +976,7 @@ VISIBILITY_PRIVATE void import_user_list(); void add_protodecoders(); void fill_syscalls_of_interest(scap_open_args *oargs); + void fill_tracepoints_of_interest(scap_open_args *oargs); void remove_thread(int64_t tid, bool force); // @@ -1116,7 +1120,7 @@ VISIBILITY_PRIVATE sinsp_filter* m_filter; std::string m_filterstring; unordered_set m_ppm_sc_of_interest; - + unordered_set m_ppm_tp_of_interest; // // Internal stats // From 9c0298c0803e332d900f5445881583aaedcae504 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 5 Aug 2022 10:43:23 +0200 Subject: [PATCH 06/29] update(scap-open): improve scap-open logging level Signed-off-by: Andrea Terzolo Co-authored-by: Federico Di Pierro --- .../libscap/examples/01-open/scap_open.c | 94 ++++++++++++++++--- 1 file changed, 83 insertions(+), 11 deletions(-) diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index fd66bc38c8..fbf9675dd7 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -20,10 +20,17 @@ limitations under the License. #include #include #include +#include #define KMOD_OPTION "--kmod" #define BPF_OPTION "--bpf" +<<<<<<< HEAD #define MODERN_BPF_OPTION "--modern_bpf" +======= +#ifdef HAS_ENGINE_MODERN_BPF +#define MODERN_BPF_OPTION "--modern_bpf" +#endif +>>>>>>> 43be7c39 (update(scap-open): improve scap-open logging level) #define SCAP_FILE_OPTION "--scap_file" #define TP_OPTION "--tp" #define PPM_SC_OPTION "--ppm_sc" @@ -50,33 +57,44 @@ struct scap_savefile_engine_params savefile_params; uint64_t num_events = UINT64_MAX; /* max number of events to catch. */ int evt_type = -1; /* event type to print. */ interesting_tp_set tp_of_interest; -bool tp_is_set; +bool tp_is_set = false; interesting_ppm_sc_set ppm_sc_of_interest; -bool ppm_sc_is_set; +bool ppm_sc_is_set = false; /* Generic global variables. */ +<<<<<<< HEAD scap_open_args oargs = {.engine_name = UNKNOWN_ENGINE}; /* scap oargs used in `scap_open`. */ uint64_t g_nevts = 0; /* total number of events captured. */ scap_t* g_h = NULL; /* global scap handler. */ uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ char* valptr = NULL; /* pointer used to print the value of event params. */ - -void enable_single_tp(const char *tp_basename) +======= +scap_open_args args = {.mode = SCAP_MODE_LIVE}; /* scap args used in `scap_open`. */ +uint64_t g_nevts = 0; /* total number of events captured. */ +scap_t* g_h = NULL; /* global scap handler. */ +uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ +char* valptr = NULL; /* pointer used to print the value of event params. */ +struct timeval tval_start, tval_end, tval_result; +>>>>>>> 43be7c39 (update(scap-open): improve scap-open logging level) + +void enable_single_tp(const char* tp_basename) { bool found = false; - for (int i = 0; i < TP_VAL_MAX && !found; i++) + + for(int i = 0; i < TP_VAL_MAX && !found; i++) { - if (strcmp(tp_names[i], tp_basename) == 0) + if(strcmp(tp_names[i], tp_basename) == 0) { tp_of_interest.tp[i] = true; found = true; } } - if (!found) + + if(!found) { fprintf(stderr, "Tracepoint '%s' not found. Unsupported or wrong parameter?\n", tp_basename); fprintf(stderr, "Please choose between:\n"); - for (int i = 0; i < TP_VAL_MAX; i++) + for(int i = 0; i < TP_VAL_MAX; i++) { fprintf(stderr, "\t* %s\n", tp_names[i]); } @@ -90,7 +108,7 @@ void enable_single_tp(const char *tp_basename) void enable_single_ppm_sc(int ppm_sc_code) { - if (ppm_sc_code < 0 || ppm_sc_code >= PPM_SC_MAX) + if(ppm_sc_code < 0 || ppm_sc_code >= PPM_SC_MAX) { fprintf(stderr, "Unexistent ppm_sc code: %d. Wrong parameter?\n", ppm_sc_code); exit(EXIT_FAILURE); @@ -99,6 +117,50 @@ void enable_single_ppm_sc(int ppm_sc_code) ppm_sc_is_set = true; } +void set_enabled_syscalls() +{ + printf("---------------------- INTERESTING SYSCALLS ----------------------\n"); + if(ppm_sc_is_set) + { + args.ppm_sc_of_interest = &ppm_sc_of_interest; + printf("* Syscall enabled:\n"); + for(int j = 0; j < PPM_SC_MAX; j++) + { + if(args.ppm_sc_of_interest->ppm_sc[j]) + { + printf("- %s\n", g_syscall_info_table[j].name); + } + } + } + else + { + printf("* All syscalls are enabled!\n"); + } + printf("------------------------------------------------------------------\n\n"); +} + +void set_enabled_tracepoint() +{ + printf("---------------------- ENABLED TRACEPOINTS ----------------------\n"); + if(tp_is_set) + { + args.tp_of_interest = &tp_of_interest; + printf("* Tracepoints enabled:\n"); + for(int j = 0; j < TP_VAL_MAX; j++) + { + if(args.tp_of_interest->tp[j]) + { + printf("- %s\n", tp_names[j]); + } + } + } + else + { + printf("* All Tracepoints are enabled!\n"); + } + printf("-----------------------------------------------------------------\n\n"); +} + /*=============================== PRINT EVENT PARAMS ===========================*/ void print_ipv4(int starting_index) @@ -535,7 +597,7 @@ void print_help() printf("'%s': enable modern BPF probe.\n", MODERN_BPF_OPTION); printf("'%s ': read events from scap file.\n", SCAP_FILE_OPTION); printf("\n------> CONFIGURATIONS OPTIONS\n"); - printf("'%s ': enable only requested tracepoint. Can be passed multiple times.\n", TP_OPTION); + printf("'%s ': enable only requested tracepoint (sys_enter, sys_exit, sched_process_exit, sched_switch, page_fault_user, page_fault_kernel, signal_deliver, sched_process_fork, sched_process_exec). Can be passed multiple times.\n", TP_OPTION); printf("'%s ': enable only requested syscall. Can be passed multiple times.\n", PPM_SC_OPTION); printf("'%s ': number of events to catch before terminating. (default: UINT64_MAX)\n", NUM_EVENTS_OPTION); printf("'%s ': every event of this type will be printed to console. (default: -1, no print)\n", EVENT_TYPE_OPTION); @@ -737,11 +799,19 @@ void parse_CLI_options(int argc, char** argv) void print_stats() { + gettimeofday(&tval_end, NULL); + timersub(&tval_end, &tval_start, &tval_result); + scap_stats s; printf("\n---------------------- STATS -----------------------\n"); printf("Events captured: %" PRIu64 "\n", g_nevts); scap_get_stats(g_h, &s); printf("Seen by driver: %" PRIu64 "\n", s.n_evts); + printf("Time elapsed: %ld s\n", tval_result.tv_sec); + if(tval_result.tv_sec != 0) + { + printf("Number of events/per-second: %ld\n", g_nevts / tval_result.tv_sec); + } printf("Number of dropped events: %" PRIu64 "\n", s.n_drops); printf("Number of dropped events caused by full buffer (total / all buffer drops - includes all categories below, likely higher than sum of syscall categories): %" PRIu64 "\n", s.n_drops_buffer); printf("Number of dropped events caused by full buffer (n_drops_buffer_clone_fork_enter syscall category): %" PRIu64 "\n", s.n_drops_buffer_clone_fork_enter); @@ -810,6 +880,8 @@ int main(int argc, char** argv) print_start_capture(); + gettimeofday(&tval_start, NULL); + while(g_nevts != num_events) { res = scap_next(g_h, &ev, &cpuid); @@ -821,7 +893,7 @@ int main(int argc, char** argv) continue; } } - + if(res == SCAP_TIMEOUT || res == SCAP_FILTERED_EVENT) { continue; From b978031ef92f070d7bdfd8a7094c59aeb28a8fd8 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Wed, 10 Aug 2022 12:35:53 +0200 Subject: [PATCH 07/29] update: disable all syscalls with `--ppm_sc -1` Signed-off-by: Andrea Terzolo Co-authored-by: Federico Di Pierro --- userspace/libscap/examples/01-open/scap_open.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index fbf9675dd7..b8c000436a 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -108,6 +108,13 @@ void enable_single_tp(const char* tp_basename) void enable_single_ppm_sc(int ppm_sc_code) { + if(ppm_sc_code == -1) + { + /* In this case we won't have any syscall enabled. */ + ppm_sc_is_set = true; + return; + } + if(ppm_sc_code < 0 || ppm_sc_code >= PPM_SC_MAX) { fprintf(stderr, "Unexistent ppm_sc code: %d. Wrong parameter?\n", ppm_sc_code); From fdc58a9be9a82d9d9650ea589ec36ed3a69b213c Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 25 Aug 2022 10:21:40 +0200 Subject: [PATCH 08/29] fix(userspace/libscap,userspace/libsinsp): multiple fixes to SCAP_EVENTMASK configuration op. Now handle->syscalls_of_interest are always kept in sync. Moreover, SCAP_EVENTMASK takes a ppm_sc that is nowadays the exposed API to play around set of syscalls. Merged scap_set_eventmask and scap_unset_eventmask in a single API. Dropped sinsp::set_eventmask and sinsp::unset_eventmask: the only API is now the new `set_syscalls_of_interest` or `mark_syscall_of_interest`. Signed-off-by: Federico Di Pierro --- userspace/libscap/engine/bpf/scap_bpf.c | 35 +------- userspace/libscap/engine/kmod/scap_kmod.c | 81 ++++++++++--------- .../libscap/examples/01-open/scap_open.c | 2 +- userspace/libscap/scap.c | 34 ++++++-- userspace/libscap/scap.h | 20 +---- userspace/libscap/scap_engine_util.c | 27 ++++--- userspace/libscap/scap_engine_util.h | 1 + userspace/libsinsp/sinsp.cpp | 44 +++++----- userspace/libsinsp/sinsp.h | 22 ----- 9 files changed, 116 insertions(+), 150 deletions(-) diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index c815d51b3c..c0e988c99d 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -1633,41 +1633,8 @@ int32_t scap_bpf_get_n_tracepoint_hit(struct scap_engine_handle engine, long* re return SCAP_SUCCESS; } -int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t event_id) { - int j; - bool quit = false; +int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) { struct bpf_engine *handle = engine.m_handle; - for(j = 0; j < SYSCALL_TABLE_SIZE && !quit; ++j) - { - /* - * In case PPM_IOCTL_MASK_ZERO_EVENTS is called, event_id will be 0. Set every syscall to false in that case. - * Otherwise, check {enter,exit} event for each syscall to see if it matches the requested event_id. - */ - if (event_id == 0 || g_syscall_table[j].enter_event_type == event_id || g_syscall_table[j].exit_event_type == event_id) - { - switch(op) - { - case PPM_IOCTL_MASK_ZERO_EVENTS: - handle->m_syscalls_of_interest[j] = false; - break; - case PPM_IOCTL_MASK_SET_EVENT: - handle->m_syscalls_of_interest[j] = true; - quit = true; - break; - case PPM_IOCTL_MASK_UNSET_EVENT: - handle->m_syscalls_of_interest[j] = false; - quit = true; - break; - default: - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "%s(%d) internal error", __FUNCTION__, op); - ASSERT(false); - return SCAP_FAILURE; - break; - } - } - } - - // Perhaps we could just update a single element here when op != PPM_IOCTL_MASK_ZERO_EVENTS ? return populate_interesting_syscalls_map(handle); } diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index 17689baed9..55b16900c7 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -249,7 +249,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) ++j; } - // Set interesting syscalls + // Set interesting syscalls, switching off any non-requested syscall for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) { if (!handle->syscalls_of_interest[i]) @@ -257,8 +257,8 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) // Kmod driver event_mask check uses event_types instead of syscall nr enum ppm_event_type enter_ev = g_syscall_table[i].enter_event_type; enum ppm_event_type exit_ev = g_syscall_table[i].exit_event_type; - scap_unset_eventmask(handle, enter_ev); - scap_unset_eventmask(handle, exit_ev); + scap_set_eventmask(handle, enter_ev, false); + scap_set_eventmask(handle, exit_ev, false); } } @@ -470,49 +470,50 @@ int32_t scap_kmod_set_snaplen(struct scap_engine_handle engine, uint32_t snaplen return SCAP_SUCCESS; } -int32_t scap_kmod_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t event_id) +int32_t scap_kmod_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) { - // - // Tell the driver to change the snaplen - // - - switch(op) { - case PPM_IOCTL_MASK_ZERO_EVENTS: - case PPM_IOCTL_MASK_SET_EVENT: - case PPM_IOCTL_MASK_UNSET_EVENT: - break; - - default: - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, "%s(%d) internal error", __FUNCTION__, op); - ASSERT(false); - return SCAP_FAILURE; - break; - } - struct scap_device_set *devset = &engine.m_handle->m_dev_set; - if(ioctl(devset->m_devs[0].m_fd, op, event_id)) + if (op != SCAP_EVENTMASK_ZERO) { - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, - "%s(%d) failed for event type %d", - __FUNCTION__, op, event_id); - ASSERT(false); - return SCAP_FAILURE; + int ioctl_op = op == SCAP_EVENTMASK_SET ? PPM_IOCTL_MASK_SET_EVENT : PPM_IOCTL_MASK_UNSET_EVENT; + // Find any syscall table entry that matches requested ppm_sc code + // then for any syscall, (un)set its enter and exit events + for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) + { + if (g_syscall_code_routing_table[i] == ppm_sc) + { + enum ppm_event_type enter_ev = g_syscall_table[i].enter_event_type; + enum ppm_event_type exit_ev = g_syscall_table[i].exit_event_type; + if(ioctl(devset->m_devs[0].m_fd, ioctl_op, enter_ev)) + { + snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, + "%s(%d) failed for event type %d", + __FUNCTION__, op, enter_ev); + ASSERT(false); + return SCAP_FAILURE; + } + if(ioctl(devset->m_devs[0].m_fd, ioctl_op, exit_ev)) + { + snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, + "%s(%d) failed for event type %d", + __FUNCTION__, op, exit_ev); + ASSERT(false); + return SCAP_FAILURE; + } + } + } } - - uint32_t j; - - // - // Force a flush of the read buffers, so we don't capture events with the old snaplen - // - for(j = 0; j < devset->m_ndevs; j++) + else { - ringbuffer_readbuf(&devset->m_devs[j], - &devset->m_devs[j].m_sn_next_event, - &devset->m_devs[j].m_sn_len); - - devset->m_devs[j].m_sn_len = 0; + if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_MASK_ZERO_EVENTS, 0)) + { + snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, + "%s(%d) failed", + __FUNCTION__, op); + ASSERT(false); + return SCAP_FAILURE; + } } - return SCAP_SUCCESS; } diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index b8c000436a..8c21ac29cf 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -130,7 +130,7 @@ void set_enabled_syscalls() if(ppm_sc_is_set) { args.ppm_sc_of_interest = &ppm_sc_of_interest; - printf("* Syscall enabled:\n"); + printf("* Syscalls enabled:\n"); for(int j = 0; j < PPM_SC_MAX; j++) { if(args.ppm_sc_of_interest->ppm_sc[j]) diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 4326f7479b..8bab83a909 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1331,11 +1331,33 @@ int64_t scap_get_readfile_offset(scap_t* handle) } } -static int32_t scap_handle_eventmask(scap_t* handle, uint32_t op, uint32_t event_id) +static int32_t scap_handle_eventmask(scap_t* handle, uint32_t op, uint32_t ppm_sc) { + switch(op) { + case SCAP_EVENTMASK_ZERO: + case SCAP_EVENTMASK_SET: + case SCAP_EVENTMASK_UNSET: + break; + + default: + snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "%s(%d) internal error", __FUNCTION__, op); + ASSERT(false); + return SCAP_FAILURE; + break; + } + + // Keep syscalls of interest in sync + if (op != SCAP_EVENTMASK_ZERO) + { + set_syscall_of_interest(ppm_sc, handle->syscalls_of_interest, op == SCAP_EVENTMASK_SET); + } + else + { + memset(handle->syscalls_of_interest, 0, sizeof(handle->syscalls_of_interest)); + } if(handle->m_vtable) { - return handle->m_vtable->configure(handle->m_engine, SCAP_EVENTMASK, op, event_id); + return handle->m_vtable->configure(handle->m_engine, SCAP_EVENTMASK, op, ppm_sc); } #if !defined(HAS_CAPTURE) || defined(_WIN32) snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "eventmask not supported on %s", PLATFORM_NAME); @@ -1355,12 +1377,8 @@ int32_t scap_clear_eventmask(scap_t* handle) { return(scap_handle_eventmask(handle, SCAP_EVENTMASK_ZERO, 0)); } -int32_t scap_set_eventmask(scap_t* handle, uint32_t event_id) { - return(scap_handle_eventmask(handle, SCAP_EVENTMASK_SET, event_id)); -} - -int32_t scap_unset_eventmask(scap_t* handle, uint32_t event_id) { - return(scap_handle_eventmask(handle, SCAP_EVENTMASK_UNSET, event_id)); +int32_t scap_set_eventmask(scap_t* handle, uint32_t ppm_sc, bool enabled) { + return(scap_handle_eventmask(handle, enabled ? SCAP_EVENTMASK_SET : SCAP_EVENTMASK_UNSET, ppm_sc)); } uint32_t scap_event_get_dump_flags(scap_t* handle) diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 720aea87e3..3acbc48c15 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -934,27 +934,15 @@ int32_t scap_set_snaplen(scap_t* handle, uint32_t snaplen); int32_t scap_clear_eventmask(scap_t* handle); /*! - \brief Set the event into the eventmask so that - users can receive the event. Useful for offloading + \brief Set the ppm_sc into the eventmask so that + users can receive the related syscalls. Useful for offloading operations such as evt.type=open \param handle Handle to the capture instance. - \param event id (example PPME_SOCKET_BIND_X) + \param ppm_sc id (example PPM_SC_EXECVE) \note This function can only be called for live captures. */ -int32_t scap_set_eventmask(scap_t* handle, uint32_t event_id); - - -/*! - \brief Unset the event into the eventmask so that - users can no longer receive the event. It is - the opposite of scap_set_eventmask - - \param handle Handle to the capture instance. - \param event id (example PPME_SOCKET_BIND_X) - \note This function can only be called for live captures. -*/ -int32_t scap_unset_eventmask(scap_t* handle, uint32_t event_id); +int32_t scap_set_eventmask(scap_t* handle, uint32_t ppm_sc, bool enabled); /*! diff --git a/userspace/libscap/scap_engine_util.c b/userspace/libscap/scap_engine_util.c index 12d3c497ab..6d09beb0f9 100644 --- a/userspace/libscap/scap_engine_util.c +++ b/userspace/libscap/scap_engine_util.c @@ -25,22 +25,27 @@ limitations under the License. #include "driver_config.h" #endif +void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable) +{ + // We need to convert from PPM_SC to SYSCALL_NR, using the routing table + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + // Find the match between the ppm_sc and the syscall_nr + if(g_syscall_code_routing_table[syscall_nr] == ppm_sc) + { + syscalls_of_interest[syscall_nr] = enable; + // DO NOT break as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) + } + } +} + void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest) { for (int i = 0; i < PPM_SC_MAX; i++) { - // We need to convert from PPM_SC to SYSCALL_NR, using the routing table - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + if (!ppm_sc_of_interest || ppm_sc_of_interest->ppm_sc[i]) { - // Find the match between the ppm_sc and the syscall_nr - if(g_syscall_code_routing_table[syscall_nr] == i) - { - if (!ppm_sc_of_interest || ppm_sc_of_interest->ppm_sc[i]) - { - syscalls_of_interest[syscall_nr] = true; - } - // DO NOT break as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) - } + set_syscall_of_interest(i, syscalls_of_interest, true); } } } diff --git a/userspace/libscap/scap_engine_util.h b/userspace/libscap/scap_engine_util.h index aa6d27e1e5..94dbce8846 100644 --- a/userspace/libscap/scap_engine_util.h +++ b/userspace/libscap/scap_engine_util.h @@ -17,5 +17,6 @@ limitations under the License. #pragma once +void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable); void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest); int32_t check_api_compatibility(scap_t *handle, char *error); diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 9c9874738f..3df1ff676e 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -457,7 +457,17 @@ void sinsp::set_import_users(bool import_users) #ifdef __linux__ void sinsp::set_syscalls_of_interest(std::unordered_set &syscalls_of_interest) { - m_ppm_sc_of_interest = syscalls_of_interest; + for (int i = 0; i < PPM_SC_MAX; i++) + { + // If the value is different, ie: either it was missing and we are adding it + // or it was present and we are removing it + if (m_ppm_sc_of_interest.find(i) != syscalls_of_interest.find(i)) + { + // if it wasn't present, it means we are actually adding a new syscall + bool adding = m_ppm_sc_of_interest.find(i) == m_ppm_sc_of_interest.end(); + mark_syscall_of_interest(i, adding); + } + } } void sinsp::set_tracepoints_of_interest(std::unordered_set &tp_of_interest) @@ -478,11 +488,20 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) { m_ppm_sc_of_interest.erase(ppm_sc); } + + if (m_inited) + { + int ret = scap_set_eventmask(m_h, ppm_sc, enabled); + if (ret != SCAP_SUCCESS) + { + throw sinsp_exception(scap_getlasterr(m_h)); + } + } } void sinsp::mark_tracepoint_of_interest(string &tp, bool enabled) { - uint32_t val = (uint32_t)tp_from_name(tp.c_str()); + auto val = (uint32_t)tp_from_name(tp.c_str()); if (val == -1) { throw sinsp_exception("unexisting tracepoint " + tp); @@ -496,6 +515,11 @@ void sinsp::mark_tracepoint_of_interest(string &tp, bool enabled) { m_ppm_tp_of_interest.erase(val); } + // TODO: unsupported for now + // if (m_inited) + // { + // int ret = scap_set_tpmask(...) + // } } void sinsp::fill_syscalls_of_interest(scap_open_args *oargs) @@ -1986,22 +2010,6 @@ sinsp_protodecoder* sinsp::require_protodecoder(string decoder_name) return m_parser->add_protodecoder(decoder_name); } -void sinsp::set_eventmask(uint32_t event_types) -{ - if (scap_set_eventmask(m_h, event_types) != SCAP_SUCCESS) - { - throw sinsp_exception(scap_getlasterr(m_h)); - } -} - -void sinsp::unset_eventmask(uint32_t event_id) -{ - if (scap_unset_eventmask(m_h, event_id) != SCAP_SUCCESS) - { - throw sinsp_exception(scap_getlasterr(m_h)); - } -} - void sinsp::protodecoder_register_reset(sinsp_protodecoder* dec) { m_decoders_reset_list.push_back(dec); diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index c7cf296d3c..d626908211 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -745,28 +745,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source return m_input_filename; } - /*! - \brief If this is an online capture, set event_id. - \param event type to set - \return SCAP_SUCCESS if the call is successful - On Failure, SCAP_FAILURE is returned and getlasterr() can be used to - obtain the cause of the error. - - \note For a list of event types, refer to \ref etypes. - */ - void set_eventmask(uint32_t event_types); - - /*! - \brief If this is an online capture, unset event_id. - \param event type to unset - \return SCAP_SUCCESS if the call is successful - On Failure, SCAP_FAILURE is returned and getlasterr() can be used to - obtain the cause of the error. - - \note For a list of event types, refer to \ref etypes. - */ - void unset_eventmask(uint32_t event_id); - /*! \brief When reading events from a trace file or a plugin, this function returns the read progress as a number between 0 and 100. From db79e540df32673f5cfe9bd4ab3e718d6c01defb Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 25 Aug 2022 10:44:53 +0200 Subject: [PATCH 09/29] fix(driver): fix build after rebase on top of master. Signed-off-by: Federico Di Pierro --- driver/event_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/driver/event_table.c b/driver/event_table.c index e347aedde6..b360aa98d4 100644 --- a/driver/event_table.c +++ b/driver/event_table.c @@ -382,8 +382,8 @@ const struct ppm_event_info g_event_info[PPM_EVENT_MAX] = { /* PPME_SYSCALL_DUP_1_X */{"dup", EC_IO_OTHER, EF_CREATES_FD | EF_USES_FD | EF_MODIFIES_STATE, 2, {{"res", PT_FD, PF_DEC}, {"oldfd", PT_FD, PF_DEC} } }, /* PPME_SYSCALL_BPF_2_E */{"bpf", EC_OTHER, EF_CREATES_FD, 1, {{"cmd", PT_INT64, PF_DEC} } }, /* PPME_SYSCALL_BPF_2_X */{"bpf", EC_OTHER, EF_CREATES_FD, 1, { {"fd", PT_FD, PF_DEC} } }, - /* PPME_SYSCALL_MLOCK2_E */{"mlock2", EC_MEMORY, EF_DROP_SIMPLE_CONS, 0}, - /* PPME_SYSCALL_MLOCK2_X */{"mlock2", EC_MEMORY, EF_DROP_SIMPLE_CONS, 4, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}, {"flags", PT_UINT32, PF_HEX, mlockall_flags}}}, + /* PPME_SYSCALL_MLOCK2_E */{"mlock2", EC_MEMORY, EF_NONE, 0}, + /* PPME_SYSCALL_MLOCK2_X */{"mlock2", EC_MEMORY, EF_NONE, 4, {{"res", PT_ERRNO, PF_DEC}, {"addr", PT_UINT64, PF_HEX}, {"len", PT_UINT64, PF_DEC}, {"flags", PT_UINT32, PF_HEX, mlockall_flags}}}, /* 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. * The number of parameters can be used to differentiate between event versions. From 42ca2f23daea0ef4ec2c5af800b88119c51e168e Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 25 Aug 2022 12:08:27 +0200 Subject: [PATCH 10/29] new(userspace/libsinsp,userspace/libscap): added a new sinsp::enforce_sinsp_syscalls_of_interest() api. The new API is needed to allow clients to guarantee to set a syscalls interesting set that contains the minimum syscalls set needed by sinsp state inspection. Moreover, fixed non-linux builds. Signed-off-by: Federico Di Pierro Co-authored-by: Andrea Terzolo --- userspace/libscap/scap.c | 32 ++++++++++++++++++++++++++++ userspace/libscap/scap.h | 5 +++++ userspace/libscap/scap_engine_util.c | 2 ++ userspace/libsinsp/sinsp.h | 6 ++++++ 4 files changed, 45 insertions(+) diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 8bab83a909..ed18e2d77b 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1180,6 +1180,38 @@ int32_t scap_get_stats(scap_t* handle, OUT scap_stats* stats) return SCAP_SUCCESS; } +uint32_t *scap_get_modifies_state_ppm_sc() +{ + static uint32_t minimum_ppm_sc_set[PPM_SC_MAX]; + // Collect EF_MODIFIES_STATE events + for (int i = 0; i < PPM_EVENT_MAX; i++) + { + if (g_event_info[i].flags & EF_MODIFIES_STATE) + { + for (int j = 0; j < SYSCALL_TABLE_SIZE; j++) + { + if (g_syscall_table[j].exit_event_type == i || g_syscall_table[j].enter_event_type == i) + { + uint32_t ppm_sc_code = g_syscall_code_routing_table[i]; + minimum_ppm_sc_set[ppm_sc_code] = 1; + } + } + } + } + + // Collect UF_NEVER_DROP syscalls + for (int j = 0; j < SYSCALL_TABLE_SIZE; j++) + { + if (g_syscall_table[j].flags & UF_NEVER_DROP) + { + uint32_t ppm_sc_code = g_syscall_code_routing_table[j]; + minimum_ppm_sc_set[ppm_sc_code] = 1; + } + } + + return minimum_ppm_sc_set; +} + // // Stop capturing the events // diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 3acbc48c15..8d44f7024e 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -830,6 +830,11 @@ scap_threadinfo* scap_get_proc_table(scap_t* handle); */ int32_t scap_get_stats(scap_t* handle, OUT scap_stats* stats); +/*! + \brief Returns the set of ppm_sc whose events have EF_MODIFIES_STATE flag or whose syscall have UF_NEVER_DROP flag. +*/ +uint32_t *scap_get_modifies_state_ppm_sc(); + /*! \brief This function can be used to temporarily interrupt event capture. diff --git a/userspace/libscap/scap_engine_util.c b/userspace/libscap/scap_engine_util.c index 6d09beb0f9..d5b3eab0d8 100644 --- a/userspace/libscap/scap_engine_util.c +++ b/userspace/libscap/scap_engine_util.c @@ -27,6 +27,7 @@ limitations under the License. void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable) { +#ifdef __linux__ // We need to convert from PPM_SC to SYSCALL_NR, using the routing table for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { @@ -37,6 +38,7 @@ void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool e // DO NOT break as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) } } +#endif } void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest) diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index d626908211..2699794233 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -955,6 +955,12 @@ VISIBILITY_PRIVATE void add_protodecoders(); void fill_syscalls_of_interest(scap_open_args *oargs); void fill_tracepoints_of_interest(scap_open_args *oargs); + + /*! + \brief Enforce minimum set of syscalls required by sinsp state collection + */ + std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = std::unordered_set(0)); + void remove_thread(int64_t tid, bool force); // From 9993fae4b4f2f96e45ac4e47ea5dfb7fe12d7b8c Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 25 Aug 2022 12:18:07 +0200 Subject: [PATCH 11/29] fix(userspace/libscap): fix windows build. Signed-off-by: Federico Di Pierro --- userspace/libscap/scap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index ed18e2d77b..02f9568a83 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1183,6 +1183,7 @@ int32_t scap_get_stats(scap_t* handle, OUT scap_stats* stats) uint32_t *scap_get_modifies_state_ppm_sc() { static uint32_t minimum_ppm_sc_set[PPM_SC_MAX]; +#ifdef __linux__ // Collect EF_MODIFIES_STATE events for (int i = 0; i < PPM_EVENT_MAX; i++) { @@ -1208,7 +1209,7 @@ uint32_t *scap_get_modifies_state_ppm_sc() minimum_ppm_sc_set[ppm_sc_code] = 1; } } - +#endif return minimum_ppm_sc_set; } From a049e16bfec199b1346ee5a11bd61fc373f9fa8d Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 25 Aug 2022 12:43:12 +0200 Subject: [PATCH 12/29] docs(userspace/libsinsp): properly state risks of playing with interesting syscalls/tracepoints sets in methods doc. Signed-off-by: Federico Di Pierro --- userspace/libsinsp/sinsp.h | 51 ++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 2699794233..9a5642b983 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -834,10 +834,56 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source // These make no sense on non-linux env #ifdef __linux__ + /*! + \brief Set desired syscalls as interesting, ie: only these syscalls will be collected. + + The function can be called both at startup time (before sinsp::open() is called), + or at runtime, and the change will immediately take effect. + + Note: playing with this could break sinsp state collection (see enforce_sinsp_syscalls_of_interest()), + or even exhibit weird leaks. + It is up to the client to know what it is doing. + */ void set_syscalls_of_interest(std::unordered_set &syscalls_of_interest); + /*! + \brief Set desired tracepoints as interesting, ie: only these tracepoints will be attached. + + The function can be only called at startup time (before sinsp::open() is called). + + Note: playing with this could break sinsp state collection, + or even exhibit weird leaks. + It is up to the client to know what it is doing. + */ void set_tracepoints_of_interest(std::unordered_set &tp_of_interest); + /*! + \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. + + The function can be called both at startup time (before sinsp::open() is called), + or at runtime, and the change will immediately take effect. + + Note: playing with this could break sinsp state collection (see enforce_sinsp_syscalls_of_interest()), + or even exhibit weird leaks. + It is up to the client to know what it is doing. + */ void mark_syscall_of_interest(uint32_t ppm_sc, bool enabled = true); + /*! + \brief Mark desired tracepoint as (un)interesting, enabling or disabling it. + + The function can be only called at startup time (before sinsp::open() is called). + + Note: playing with this could break sinsp state collection (see enforce_sinsp_syscalls_of_interest()), + or even exhibit weird leaks. + It is up to the client to know what it is doing. + */ void mark_tracepoint_of_interest(string &tp, bool enabled = true); + /*! + \brief Enforce minimum set of syscalls required by sinsp state collection. + + Note: without using this method, we cannot guarantee that sinsp state + will always be up to date, or even work at all. + */ + std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = std::unordered_set(0)); + #endif bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress); void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo); @@ -956,11 +1002,6 @@ VISIBILITY_PRIVATE void fill_syscalls_of_interest(scap_open_args *oargs); void fill_tracepoints_of_interest(scap_open_args *oargs); - /*! - \brief Enforce minimum set of syscalls required by sinsp state collection - */ - std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = std::unordered_set(0)); - void remove_thread(int64_t tid, bool force); // From 1e75573be8d6cbdd75114186ef01fc0a55ac2740 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 26 Aug 2022 12:27:32 +0000 Subject: [PATCH 13/29] update(libsinsp)!: refactor the APIs to use with syscalls and tracepoints Signed-off-by: Andrea Terzolo --- userspace/libsinsp/event.cpp | 12 +----- userspace/libsinsp/sinsp.cpp | 49 +++++++++++++++--------- userspace/libsinsp/sinsp.h | 73 ++++++++++++++---------------------- 3 files changed, 61 insertions(+), 73 deletions(-) diff --git a/userspace/libsinsp/event.cpp b/userspace/libsinsp/event.cpp index 57f4c5d095..039d633b9e 100644 --- a/userspace/libsinsp/event.cpp +++ b/userspace/libsinsp/event.cpp @@ -2671,16 +2671,6 @@ scap_dump_flags sinsp_evt::get_dump_flags(OUT bool* should_drop) bool sinsp_evt::should_consider() { uint16_t etype = get_type(); - - if(etype == PPME_GENERIC_E || etype == PPME_GENERIC_X) - { - sinsp_evt_param *parinfo = get_param(0); - ASSERT(parinfo->m_len == sizeof(uint16_t)); - uint16_t scid = *(uint16_t *)parinfo->m_val; - - return sinsp::should_consider_syscallid(scid); - } - return sinsp::should_consider_evtnum(etype); } @@ -2811,4 +2801,4 @@ bool sinsp_evt::clone_event(sinsp_evt &dest, const sinsp_evt &src) dest.m_fdinfo_name_changed = src.m_fdinfo_name_changed; return true; -} \ No newline at end of file +} diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 3df1ff676e..dc3aeba228 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -73,8 +73,6 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str m_lastevent_ts(0), m_container_manager(this, static_container, static_id, static_name, static_image), m_usergroup_manager(this), - m_ppm_sc_of_interest(), - m_ppm_tp_of_interest(), m_suppressed_comms(), m_inited(false) { @@ -168,6 +166,18 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str m_replay_scap_evt = NULL; m_plugin_manager = new sinsp_plugin_manager(); + + /* Set all syscall interesting by default. */ + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + m_ppm_sc_of_interest.insert(ppm_sc); + } + + /* Set all tracepoints interesting by default. */ + for(int tp_val = 0; tp_val < TP_VAL_MAX; tp_val++) + { + m_ppm_tp_of_interest.insert(tp_val); + } } sinsp::~sinsp() @@ -455,26 +465,31 @@ void sinsp::set_import_users(bool import_users) } #ifdef __linux__ -void sinsp::set_syscalls_of_interest(std::unordered_set &syscalls_of_interest) +void sinsp::initialize_syscalls_of_interest(std::unordered_set &syscalls_of_interest) { - for (int i = 0; i < PPM_SC_MAX; i++) + /* Clean the actual set. */ + m_ppm_sc_of_interest.clear(); + + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - // If the value is different, ie: either it was missing and we are adding it - // or it was present and we are removing it - if (m_ppm_sc_of_interest.find(i) != syscalls_of_interest.find(i)) + if(syscalls_of_interest.find(ppm_sc) != syscalls_of_interest.end()) { - // if it wasn't present, it means we are actually adding a new syscall - bool adding = m_ppm_sc_of_interest.find(i) == m_ppm_sc_of_interest.end(); - mark_syscall_of_interest(i, adding); + m_ppm_sc_of_interest.insert(ppm_sc); } } } -void sinsp::set_tracepoints_of_interest(std::unordered_set &tp_of_interest) +void sinsp::initialize_tracepoints_of_interest(std::unordered_set &tp_of_interest) { + m_ppm_tp_of_interest.clear(); for (auto tp : tp_of_interest) { - mark_tracepoint_of_interest(tp, true); + auto val = (uint32_t)tp_from_name(tp.c_str()); + if (val == -1) + { + throw sinsp_exception("unexisting tracepoint " + tp); + } + m_ppm_tp_of_interest.insert(val); } } @@ -489,13 +504,10 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) m_ppm_sc_of_interest.erase(ppm_sc); } - if (m_inited) + int ret = scap_set_eventmask(m_h, ppm_sc, enabled); + if (ret != SCAP_SUCCESS) { - int ret = scap_set_eventmask(m_h, ppm_sc, enabled); - if (ret != SCAP_SUCCESS) - { - throw sinsp_exception(scap_getlasterr(m_h)); - } + throw sinsp_exception(scap_getlasterr(m_h)); } } @@ -826,6 +838,7 @@ void sinsp::close() } m_ppm_sc_of_interest.clear(); + m_ppm_tp_of_interest.clear(); } // diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 9a5642b983..e8f9abd166 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -835,51 +835,45 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source // These make no sense on non-linux env #ifdef __linux__ /*! - \brief Set desired syscalls as interesting, ie: only these syscalls will be collected. + \brief Set desired syscalls as interesting, ie: only these syscalls will be collected. + Please note that this method must be called before opening the inspector otherwise, + all the syscall will be set as interesting by default. - The function can be called both at startup time (before sinsp::open() is called), - or at runtime, and the change will immediately take effect. - - Note: playing with this could break sinsp state collection (see enforce_sinsp_syscalls_of_interest()), - or even exhibit weird leaks. - It is up to the client to know what it is doing. + WARNING: playing with this API could break `libsinsp` state collection if you want to + be sure that your syscall set doesn't break the `libsinsp` state collection you + have to use the `enforce_sinsp_syscalls_of_interest()` API. + It is up to the client to know what it is doing! */ - void set_syscalls_of_interest(std::unordered_set &syscalls_of_interest); - /*! - \brief Set desired tracepoints as interesting, ie: only these tracepoints will be attached. + void initialize_syscalls_of_interest(std::unordered_set &syscalls_of_interest); - The function can be only called at startup time (before sinsp::open() is called). + /*! + \brief Set desired tracepoints as interesting, ie: only these tracepoints will be attached. + Please note that this method must be called before opening the inspector otherwise, + all the tracepoints will be set as interesting by default. - Note: playing with this could break sinsp state collection, - or even exhibit weird leaks. - It is up to the client to know what it is doing. + WARNING: playing with this API could break `libsinsp` state collection if you want to + be sure that your tracepoint set doesn't break the `libsinsp` state collection don't + use this API, this is only useful in advanced cases where the client needs to know what + it is doing! */ - void set_tracepoints_of_interest(std::unordered_set &tp_of_interest); - /*! - \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. + void initialize_tracepoints_of_interest(std::unordered_set &tp_of_interest); - The function can be called both at startup time (before sinsp::open() is called), - or at runtime, and the change will immediately take effect. + /*! + \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. + Please note that this method must be called when the inspector is already open to + modify at runtime the interesting syscall set. - Note: playing with this could break sinsp state collection (see enforce_sinsp_syscalls_of_interest()), - or even exhibit weird leaks. - It is up to the client to know what it is doing. + WARNING: playing with this API could break `libsinsp` state collection, this is only + useful in advanced cases where the client needs to know what it is doing! */ void mark_syscall_of_interest(uint32_t ppm_sc, bool enabled = true); - /*! - \brief Mark desired tracepoint as (un)interesting, enabling or disabling it. - The function can be only called at startup time (before sinsp::open() is called). - - Note: playing with this could break sinsp state collection (see enforce_sinsp_syscalls_of_interest()), - or even exhibit weird leaks. - It is up to the client to know what it is doing. - */ - void mark_tracepoint_of_interest(string &tp, bool enabled = true); /*! - \brief Enforce minimum set of syscalls required by sinsp state collection. + \brief Provide the minimum set of syscalls required by sinsp state collection. + If you call it without arguments it returns a new set with just these syscalls + otherwise, it merges the minimum set of syscalls with the one you provided. - Note: without using this method, we cannot guarantee that sinsp state + WARNING: without using this method, we cannot guarantee that `libsinsp` state will always be up to date, or even work at all. */ std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = std::unordered_set(0)); @@ -922,14 +916,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source { enum ppm_event_flags flags = g_infotables.m_event_info[etype].flags; - return ! (flags & sinsp::event_skip_flags()); - } - - static inline bool should_consider_syscallid(uint16_t scid) - { - enum ppm_event_flags flags = g_infotables.m_syscall_info_table[scid].flags; - - return ! (flags & sinsp::event_skip_flags()); + return !(flags & sinsp::event_skip_flags()); } // Add comm to the list of comms for which the inspector @@ -982,7 +969,7 @@ VISIBILITY_PRIVATE static inline ppm_event_flags event_skip_flags() { - return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED | EF_OLD_VERSION); + return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED); } // Doxygen doesn't understand VISIBILITY_PRIVATE #ifdef _DOXYGEN @@ -999,8 +986,6 @@ VISIBILITY_PRIVATE void import_ifaddr_list(); void import_user_list(); void add_protodecoders(); - void fill_syscalls_of_interest(scap_open_args *oargs); - void fill_tracepoints_of_interest(scap_open_args *oargs); void remove_thread(int64_t tid, bool force); From a46471c6c20d36c579fcbaee384120855f37267c Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Fri, 26 Aug 2022 16:17:51 +0200 Subject: [PATCH 14/29] update(userspace): complete the rebase from master after #540. Signed-off-by: Federico Di Pierro Co-authored-by: Andrea Terzolo --- userspace/libscap/engine/bpf/bpf.h | 2 +- userspace/libscap/engine/bpf/scap_bpf.c | 4 +- userspace/libscap/engine/kmod/scap_kmod.c | 11 +- .../engine/modern_bpf/scap_modern_bpf.c | 2 +- userspace/libscap/engine/udig/udig_public.h | 5 - .../libscap/examples/01-open/scap_open.c | 52 +++---- userspace/libscap/scap.c | 11 -- userspace/libscap/scap_open.h | 8 +- userspace/libsinsp/examples/test.cpp | 2 +- userspace/libsinsp/sinsp.cpp | 135 +++++++----------- userspace/libsinsp/sinsp.h | 41 ++---- 11 files changed, 90 insertions(+), 183 deletions(-) diff --git a/userspace/libscap/engine/bpf/bpf.h b/userspace/libscap/engine/bpf/bpf.h index b62ef242fc..5313c185b8 100644 --- a/userspace/libscap/engine/bpf/bpf.h +++ b/userspace/libscap/engine/bpf/bpf.h @@ -34,7 +34,7 @@ limitations under the License. struct bpf_engine { struct scap_device_set m_dev_set; - bool m_syscalls_of_interest[SYSCALL_TABLE_SIZE]; + bool *m_syscalls_of_interest; size_t m_ncpus; char* m_lasterr; int m_bpf_prog_fds[BPF_PROGS_MAX]; diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index c0e988c99d..98a0c72224 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -1717,7 +1717,9 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) engine.m_handle->m_ncpus = num_cpus; - fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, engine.m_handle->m_syscalls_of_interest); + fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, handle->syscalls_of_interest); + // Make internal syscalls of interest point to scap_t syscalls of interest, to keep them updated + engine.m_handle->m_syscalls_of_interest = handle->syscalls_of_interest; rc = devset_init(&engine.m_handle->m_dev_set, num_cpus, engine.m_handle->m_lasterr); if(rc != SCAP_SUCCESS) diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index 55b16900c7..a6d76e32be 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -108,7 +108,8 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) { return rc; } - fill_syscalls_of_interest(oargs->ppm_sc_of_interest, handle->syscalls_of_interest); + + fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, handle->syscalls_of_interest); // // Allocate the device descriptors. @@ -254,11 +255,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) { if (!handle->syscalls_of_interest[i]) { - // Kmod driver event_mask check uses event_types instead of syscall nr - enum ppm_event_type enter_ev = g_syscall_table[i].enter_event_type; - enum ppm_event_type exit_ev = g_syscall_table[i].exit_event_type; - scap_set_eventmask(handle, enter_ev, false); - scap_set_eventmask(handle, exit_ev, false); + scap_set_eventmask(handle, g_syscall_code_routing_table[i], false); } } @@ -266,7 +263,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) uint32_t tp_of_interest = 0; for (int i = 0; i < TP_VAL_MAX; i++) { - if (!oargs->tp_of_interest || oargs->tp_of_interest->tp[i]) + if (oargs->tp_of_interest.tp[i]) { tp_of_interest |= (1 << i); } diff --git a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c index 565582b912..19ef0c833f 100644 --- a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c +++ b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c @@ -146,7 +146,7 @@ int32_t scap_modern_bpf__init(scap_t* handle, scap_open_args* oargs) handle->m_schema_version = pman_get_probe_schema_ver(); /// TODO: Here we miss the simple consumer logic. Right now - /// all syscalls are interesting. + /// all syscalls and tracepoints are interesting. return SCAP_SUCCESS; } diff --git a/userspace/libscap/engine/udig/udig_public.h b/userspace/libscap/engine/udig/udig_public.h index c976ed3681..f142c6b259 100644 --- a/userspace/libscap/engine/udig/udig_public.h +++ b/userspace/libscap/engine/udig/udig_public.h @@ -23,11 +23,6 @@ extern "C" { #endif - struct scap_udig_engine_params - { - uint64_t single_buffer_dim; ///< dim of a single shared buffer. Usually, we have one buffer for every online CPU. - }; - #ifdef __cplusplus }; #endif diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 8c21ac29cf..4f848df7aa 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -24,13 +24,7 @@ limitations under the License. #define KMOD_OPTION "--kmod" #define BPF_OPTION "--bpf" -<<<<<<< HEAD #define MODERN_BPF_OPTION "--modern_bpf" -======= -#ifdef HAS_ENGINE_MODERN_BPF -#define MODERN_BPF_OPTION "--modern_bpf" -#endif ->>>>>>> 43be7c39 (update(scap-open): improve scap-open logging level) #define SCAP_FILE_OPTION "--scap_file" #define TP_OPTION "--tp" #define PPM_SC_OPTION "--ppm_sc" @@ -56,26 +50,16 @@ struct scap_savefile_engine_params savefile_params; /* Configuration variables set through CLI. */ uint64_t num_events = UINT64_MAX; /* max number of events to catch. */ int evt_type = -1; /* event type to print. */ -interesting_tp_set tp_of_interest; -bool tp_is_set = false; -interesting_ppm_sc_set ppm_sc_of_interest; -bool ppm_sc_is_set = false; +bool ppm_sc_is_set; +bool tp_is_set; /* Generic global variables. */ -<<<<<<< HEAD scap_open_args oargs = {.engine_name = UNKNOWN_ENGINE}; /* scap oargs used in `scap_open`. */ uint64_t g_nevts = 0; /* total number of events captured. */ scap_t* g_h = NULL; /* global scap handler. */ uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ -char* valptr = NULL; /* pointer used to print the value of event params. */ -======= -scap_open_args args = {.mode = SCAP_MODE_LIVE}; /* scap args used in `scap_open`. */ -uint64_t g_nevts = 0; /* total number of events captured. */ -scap_t* g_h = NULL; /* global scap handler. */ -uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ -char* valptr = NULL; /* pointer used to print the value of event params. */ +char* valptr = NULL; /* pointer used to print the value of event params. */ /* pointer used to print the value of event params. */ struct timeval tval_start, tval_end, tval_result; ->>>>>>> 43be7c39 (update(scap-open): improve scap-open logging level) void enable_single_tp(const char* tp_basename) { @@ -85,7 +69,7 @@ void enable_single_tp(const char* tp_basename) { if(strcmp(tp_names[i], tp_basename) == 0) { - tp_of_interest.tp[i] = true; + oargs.tp_of_interest.tp[i] = true; found = true; } } @@ -120,7 +104,7 @@ void enable_single_ppm_sc(int ppm_sc_code) fprintf(stderr, "Unexistent ppm_sc code: %d. Wrong parameter?\n", ppm_sc_code); exit(EXIT_FAILURE); } - ppm_sc_of_interest.ppm_sc[ppm_sc_code] = true; + oargs.ppm_sc_of_interest.ppm_sc[ppm_sc_code] = true; ppm_sc_is_set = true; } @@ -129,11 +113,10 @@ void set_enabled_syscalls() printf("---------------------- INTERESTING SYSCALLS ----------------------\n"); if(ppm_sc_is_set) { - args.ppm_sc_of_interest = &ppm_sc_of_interest; printf("* Syscalls enabled:\n"); for(int j = 0; j < PPM_SC_MAX; j++) { - if(args.ppm_sc_of_interest->ppm_sc[j]) + if(oargs.ppm_sc_of_interest.ppm_sc[j]) { printf("- %s\n", g_syscall_info_table[j].name); } @@ -142,6 +125,11 @@ void set_enabled_syscalls() else { printf("* All syscalls are enabled!\n"); + for(int j = 0; j < PPM_SC_MAX; j++) + { + oargs.ppm_sc_of_interest.ppm_sc[j] = true; + } + } printf("------------------------------------------------------------------\n\n"); } @@ -151,11 +139,10 @@ void set_enabled_tracepoint() printf("---------------------- ENABLED TRACEPOINTS ----------------------\n"); if(tp_is_set) { - args.tp_of_interest = &tp_of_interest; printf("* Tracepoints enabled:\n"); for(int j = 0; j < TP_VAL_MAX; j++) { - if(args.tp_of_interest->tp[j]) + if(oargs.tp_of_interest.tp[j]) { printf("- %s\n", tp_names[j]); } @@ -164,6 +151,10 @@ void set_enabled_tracepoint() else { printf("* All Tracepoints are enabled!\n"); + for(int j = 0; j < TP_VAL_MAX; j++) + { + oargs.tp_of_interest.tp[j] = true; + } } printf("-----------------------------------------------------------------\n\n"); } @@ -865,15 +856,6 @@ int main(int argc, char** argv) parse_CLI_options(argc, argv); - if (ppm_sc_is_set) - { - oargs.ppm_sc_of_interest = ppm_sc_of_interest; - } - if (tp_is_set) - { - oargs.tp_of_interest = tp_of_interest; - } - print_scap_source(); print_configurations(); @@ -921,6 +903,8 @@ int main(int argc, char** argv) print_event(ev); } g_nevts++; + printf("topekke %d\n", ev->type); + scap_set_eventmask(g_h, 28, false); } print_stats(); diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 02f9568a83..36b924b23a 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -83,18 +83,7 @@ static int32_t copy_comms(scap_t *handle, const char **suppressed_comms) } #if !defined(HAS_CAPTURE) || defined(CYGWING_AGENT) || defined(_WIN32) -<<<<<<< HEAD scap_t* scap_open_live_int(char *error, int32_t *rc, scap_open_args* oargs) -======= -scap_t* scap_open_live_int(char *error, int32_t *rc, - proc_entry_callback proc_callback, - void* proc_callback_context, - bool import_users, - const char *bpf_probe, - const char **suppressed_comms, - interesting_ppm_sc_set *ppm_sc_of_interest, - interesting_tp_set *tp_of_interest) ->>>>>>> 717ab7c5 (new(driver, userspace/libscap): add a new scap_open argument to choose set of tracepoints to be attached.) { snprintf(error, SCAP_LASTERR_SIZE, "live capture not supported on %s", PLATFORM_NAME); *rc = SCAP_NOT_SUPPORTED; diff --git a/userspace/libscap/scap_open.h b/userspace/libscap/scap_open.h index 2be5a3079d..12cb081fb9 100644 --- a/userspace/libscap/scap_open.h +++ b/userspace/libscap/scap_open.h @@ -32,10 +32,8 @@ limitations under the License. #include "../../driver/ppm_tp.h" #ifdef __cplusplus -<<<<<<< HEAD extern "C" -======= -extern "C" { +{ #endif /*! @@ -102,8 +100,8 @@ typedef struct scap_open_args // events should be returned, with a trailing NULL value. // You can provide additional comm // values via scap_suppress_events_comm(). - interesting_ppm_sc_set ppm_sc_of_interest; ///< syscalls of interest. - interesting_tp_set tp_of_interest; ///< tp of interest + interesting_ppm_sc_set ppm_sc_of_interest; ///< syscalls of interest. If left empty, no syscalls will be captured + interesting_tp_set tp_of_interest; ///< tp of interest. If left empty, no tracepoints will be attached void* engine_params; ///< engine-specific params. } scap_open_args; diff --git a/userspace/libsinsp/examples/test.cpp b/userspace/libsinsp/examples/test.cpp index 0c652b98c9..36faa25556 100644 --- a/userspace/libsinsp/examples/test.cpp +++ b/userspace/libsinsp/examples/test.cpp @@ -160,7 +160,7 @@ void open_engine(sinsp& inspector) } else if(!engine_string.compare(UDIG_ENGINE)) { - inspector.open_udig(buffer_dim); + inspector.open_udig(); } else if(!engine_string.compare(NODRIVER_ENGINE)) { diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index dc3aeba228..5b682b00cf 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -166,18 +166,6 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str m_replay_scap_evt = NULL; m_plugin_manager = new sinsp_plugin_manager(); - - /* Set all syscall interesting by default. */ - for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) - { - m_ppm_sc_of_interest.insert(ppm_sc); - } - - /* Set all tracepoints interesting by default. */ - for(int tp_val = 0; tp_val < TP_VAL_MAX; tp_val++) - { - m_ppm_tp_of_interest.insert(tp_val); - } } sinsp::~sinsp() @@ -464,46 +452,16 @@ void sinsp::set_import_users(bool import_users) m_usergroup_manager.m_import_users = import_users; } -#ifdef __linux__ -void sinsp::initialize_syscalls_of_interest(std::unordered_set &syscalls_of_interest) -{ - /* Clean the actual set. */ - m_ppm_sc_of_interest.clear(); - - for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) - { - if(syscalls_of_interest.find(ppm_sc) != syscalls_of_interest.end()) - { - m_ppm_sc_of_interest.insert(ppm_sc); - } - } -} - -void sinsp::initialize_tracepoints_of_interest(std::unordered_set &tp_of_interest) -{ - m_ppm_tp_of_interest.clear(); - for (auto tp : tp_of_interest) - { - auto val = (uint32_t)tp_from_name(tp.c_str()); - if (val == -1) - { - throw sinsp_exception("unexisting tracepoint " + tp); - } - m_ppm_tp_of_interest.insert(val); - } -} - void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) { - if (enabled) + if (!m_inited) { - m_ppm_sc_of_interest.insert(ppm_sc); + throw sinsp_exception("you cannot used this method before opening the inspector."); } - else + if (ppm_sc >= PPM_SC_MAX || ppm_sc < 0) { - m_ppm_sc_of_interest.erase(ppm_sc); + throw sinsp_exception("unexistent ppm_sc code."); } - int ret = scap_set_eventmask(m_h, ppm_sc, enabled); if (ret != SCAP_SUCCESS) { @@ -511,49 +469,60 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) } } -void sinsp::mark_tracepoint_of_interest(string &tp, bool enabled) +std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest) { - auto val = (uint32_t)tp_from_name(tp.c_str()); - if (val == -1) + uint32_t *minimum_syscalls = scap_get_modifies_state_ppm_sc(); + for (int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - throw sinsp_exception("unexisting tracepoint " + tp); + if (minimum_syscalls[ppm_sc]) + { + syscalls_of_interest.insert(ppm_sc); + } } + return syscalls_of_interest; +} - if (enabled) - { - m_ppm_tp_of_interest.insert(val); - } - else +void sinsp::fill_syscalls_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest) +{ + // Finally, set scap_open_args syscalls_of_interest + for (int i = 0; i < PPM_SC_MAX; i++) { - m_ppm_tp_of_interest.erase(val); + if (syscalls_of_interest.empty()) + { + oargs->ppm_sc_of_interest.ppm_sc[i] = 1; + } + else + { + oargs->ppm_sc_of_interest.ppm_sc[i] = syscalls_of_interest.find(i) != syscalls_of_interest.end(); + } } - // TODO: unsupported for now - // if (m_inited) - // { - // int ret = scap_set_tpmask(...) - // } } -void sinsp::fill_syscalls_of_interest(scap_open_args *oargs) +void sinsp::fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest) { - // Fallback to set all events as interesting - if (m_mode != SCAP_MODE_LIVE || m_ppm_sc_of_interest.empty()) + if (!tp_of_interest.empty()) { - // Default NULL value will handle everything for us - return; + for(const auto& tp : tp_of_interest) + { + auto val = (uint32_t)tp_from_name(tp.c_str()); + if(val == -1) + { + throw sinsp_exception("unexisting tracepoint " + tp); + } + oargs->tp_of_interest.tp[val] = true; + } } - - static interesting_ppm_sc_set ppm_sc_of_interest; - - // Finally, set scap_open_args syscalls_of_interest - for (int i = 0; i < PPM_SC_MAX; i++) + else { - ppm_sc_of_interest.ppm_sc[i] = m_ppm_sc_of_interest.find(i) != m_ppm_sc_of_interest.end(); + for (int i = 0; i < TP_VAL_MAX; i++) + { + oargs->tp_of_interest.tp[i] = true; + } } - oargs->ppm_sc_of_interest = &ppm_sc_of_interest; + } -void sinsp::open_common(scap_open_args* oargs) +void sinsp::open_common(scap_open_args* oargs, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) { char error[SCAP_LASTERR_SIZE] = {0}; g_logger.log("Trying to open the right engine!"); @@ -564,7 +533,9 @@ void sinsp::open_common(scap_open_args* oargs) /* We need to save the actual mode and the engine used by the inspector. */ m_mode = oargs->mode; - fill_syscalls_of_interest(oargs); + fill_syscalls_of_interest(oargs, syscalls_of_interest); + fill_tp_of_interest(oargs, tp_of_interest); + if(!m_filter_proc_table_when_saving) { oargs->proc_callback = ::on_new_entry_from_proc; @@ -594,7 +565,7 @@ scap_open_args sinsp::factory_open_args(const char* engine_name, scap_mode_t sca return oargs; } -void sinsp::open_kmod(uint64_t buffer_dimension) +void sinsp::open_kmod(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) { scap_open_args oargs = factory_open_args(KMOD_ENGINE, SCAP_MODE_LIVE); struct scap_kmod_engine_params params; @@ -604,7 +575,7 @@ void sinsp::open_kmod(uint64_t buffer_dimension) } /* We cannot trust the client to validate arguments we need to do it here. */ -void sinsp::open_bpf(uint64_t buffer_dimension, const char* bpf_path) +void sinsp::open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) { if(!bpf_path) { @@ -619,12 +590,9 @@ void sinsp::open_bpf(uint64_t buffer_dimension, const char* bpf_path) open_common(&oargs); } -void sinsp::open_udig(uint64_t buffer_dimension) +void sinsp::open_udig() { scap_open_args oargs = factory_open_args(UDIG_ENGINE, SCAP_MODE_LIVE); - struct scap_udig_engine_params params; - params.single_buffer_dim = buffer_dimension; - oargs.engine_params = ¶ms; open_common(&oargs); } @@ -708,7 +676,7 @@ void sinsp::open_gvisor(std::string config_path, std::string root_path) set_get_procs_cpu_from_driver(false); } -void sinsp::open_modern_bpf(uint64_t buffer_dimension) +void sinsp::open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interes) { scap_open_args oargs = factory_open_args(MODERN_BPF_ENGINE, SCAP_MODE_LIVE); struct scap_modern_bpf_engine_params params; @@ -836,9 +804,6 @@ void sinsp::close() delete m_filter; m_filter = NULL; } - - m_ppm_sc_of_interest.clear(); - m_ppm_tp_of_interest.clear(); } // diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index e8f9abd166..888bfd24fa 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -219,14 +219,14 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source /* Wrappers to open a specific engine. */ - void open_kmod(uint64_t buffer_dimension); - void open_bpf(uint64_t buffer_dimension, const char* bpf_path); - void open_udig(uint64_t buffer_dimension); + void open_kmod(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); + void open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); + void open_udig(); void open_nodriver(); void open_savefile(const std::string &filename, int fd); void open_plugin(std::string plugin_name, std::string plugin_open_params); void open_gvisor(std::string config_path, std::string root_path); - void open_modern_bpf(uint64_t buffer_dimension); + void open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); void open_test_input(scap_test_input_data *data); scap_open_args factory_open_args(const char* engine, scap_mode_t scap_mode); @@ -834,29 +834,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source // These make no sense on non-linux env #ifdef __linux__ - /*! - \brief Set desired syscalls as interesting, ie: only these syscalls will be collected. - Please note that this method must be called before opening the inspector otherwise, - all the syscall will be set as interesting by default. - - WARNING: playing with this API could break `libsinsp` state collection if you want to - be sure that your syscall set doesn't break the `libsinsp` state collection you - have to use the `enforce_sinsp_syscalls_of_interest()` API. - It is up to the client to know what it is doing! - */ - void initialize_syscalls_of_interest(std::unordered_set &syscalls_of_interest); - - /*! - \brief Set desired tracepoints as interesting, ie: only these tracepoints will be attached. - Please note that this method must be called before opening the inspector otherwise, - all the tracepoints will be set as interesting by default. - - WARNING: playing with this API could break `libsinsp` state collection if you want to - be sure that your tracepoint set doesn't break the `libsinsp` state collection don't - use this API, this is only useful in advanced cases where the client needs to know what - it is doing! - */ - void initialize_tracepoints_of_interest(std::unordered_set &tp_of_interest); /*! \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. @@ -876,8 +853,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source WARNING: without using this method, we cannot guarantee that `libsinsp` state will always be up to date, or even work at all. */ - std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = std::unordered_set(0)); - + std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = {}); #endif bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress); void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo); @@ -977,7 +953,7 @@ VISIBILITY_PRIVATE #endif void set_input_plugin(const string& name, const string& params); - void open_common(scap_open_args* oargs); + void open_common(scap_open_args* oargs, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); void init(); void deinit_state(); void consume_initialstate_events(); @@ -989,6 +965,9 @@ VISIBILITY_PRIVATE void remove_thread(int64_t tid, bool force); + void fill_syscalls_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest); + void fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest); + // // Note: lookup_only should be used when the query for the thread is made // not as a consequence of an event for that thread arriving, but @@ -1129,8 +1108,6 @@ VISIBILITY_PRIVATE uint64_t m_firstevent_ts; sinsp_filter* m_filter; std::string m_filterstring; - unordered_set m_ppm_sc_of_interest; - unordered_set m_ppm_tp_of_interest; // // Internal stats // From e5689fd66ae39f18bc57db55c03e21fcce7f4418 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Fri, 26 Aug 2022 16:33:29 +0200 Subject: [PATCH 15/29] update(userspace): some small fixes after rebase. Signed-off-by: Federico Di Pierro --- .../libscap/examples/01-open/scap_open.c | 2 - userspace/libscap/scap_open.h | 120 +++++++++--------- userspace/libsinsp/sinsp.cpp | 2 +- userspace/libsinsp/sinsp.h | 5 +- 4 files changed, 60 insertions(+), 69 deletions(-) diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 4f848df7aa..72ae8b521d 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -903,8 +903,6 @@ int main(int argc, char** argv) print_event(ev); } g_nevts++; - printf("topekke %d\n", ev->type); - scap_set_eventmask(g_h, 28, false); } print_stats(); diff --git a/userspace/libscap/scap_open.h b/userspace/libscap/scap_open.h index 12cb081fb9..a89ee14ff4 100644 --- a/userspace/libscap/scap_open.h +++ b/userspace/libscap/scap_open.h @@ -36,74 +36,70 @@ extern "C" { #endif -/*! - \brief Arguments for scap_open -*/ -typedef enum { - /*! - * Default value that mostly exists so that sinsp can have a valid value - * before it is initialized. - */ - SCAP_MODE_NONE = 0, - /*! - * Read system call data from a capture file. - */ - SCAP_MODE_CAPTURE, - /*! - * Read system call data from the underlying operating system. - */ - SCAP_MODE_LIVE, /*! - * Do not read system call data. If next is called, a dummy event is - * returned. - */ - SCAP_MODE_NODRIVER, + \brief Scap possible modes + */ + typedef enum + { + /*! + * Default value that mostly exists so that sinsp can have a valid value + * before it is initialized. + */ + SCAP_MODE_NONE = 0, + /*! + * Read system call data from a capture file. + */ + SCAP_MODE_CAPTURE, + /*! + * Read system call data from the underlying operating system. + */ + SCAP_MODE_LIVE, + /*! + * Do not read system call data. If next is called, a dummy event is + * returned. + */ + SCAP_MODE_NODRIVER, + /*! + * Do not read system call data. Events come from the configured input plugin. + */ + SCAP_MODE_PLUGIN, + } scap_mode_t; + /*! - * Do not read system call data. Events come from the configured input plugin. + * \brief Argument for scap_open + * Set any PPM_SC syscall idx to true to enable its tracing at driver level, + * otherwise syscalls are not traced (so called "uninteresting syscalls"). */ - SCAP_MODE_PLUGIN, -#ifdef HAS_ENGINE_MODERN_BPF + typedef struct + { + bool ppm_sc[PPM_SC_MAX]; + } interesting_ppm_sc_set; + /*! - * Read system call data from the underlying operating system using a modern - * bpf probe. + * \brief Argument for scap_open + * Set any tracepoint idx to true to enable its tracing at driver level, + * otherwise a tp is not attached (so called "uninteresting tracepoint"). */ - SCAP_MODE_MODERN_BPF, -#endif -} scap_mode_t; - -/*! - \brief Argument for scap_open - Set any PPM_SC syscall idx to true to enable its tracing at driver level, - otherwise syscalls are not traced (so called "uninteresting syscalls"). -*/ -typedef struct { - bool ppm_sc[PPM_SC_MAX]; -} interesting_ppm_sc_set; - -/*! - \brief Argument for scap_open - Set any tracepoint idx to true to enable its tracing at driver level, - otherwise a tp is not attached (so called "uninteresting tracepoint"). -*/ -typedef struct { - bool tp[TP_VAL_MAX]; -} interesting_tp_set; + typedef struct + { + bool tp[TP_VAL_MAX]; + } interesting_tp_set; -typedef struct scap_open_args -{ - const char* engine_name; ///< engine name ("kmod", "bpf", ...). - scap_mode_t mode; ///< scap-mode required by the engine. - proc_entry_callback proc_callback; ///< Callback to be invoked for each thread/fd that is extracted from /proc, or NULL if no callback is needed. - void* proc_callback_context; ///< Opaque pointer that will be included in the calls to proc_callback. Ignored if proc_callback is NULL. - bool import_users; ///< true if the user list should be created when opening the capture. - const char* suppressed_comms[SCAP_MAX_SUPPRESSED_COMMS]; ///< A list of processes (comm) for which no - // events should be returned, with a trailing NULL value. - // You can provide additional comm - // values via scap_suppress_events_comm(). - interesting_ppm_sc_set ppm_sc_of_interest; ///< syscalls of interest. If left empty, no syscalls will be captured - interesting_tp_set tp_of_interest; ///< tp of interest. If left empty, no tracepoints will be attached - void* engine_params; ///< engine-specific params. -} scap_open_args; + typedef struct scap_open_args + { + const char* engine_name; ///< engine name ("kmod", "bpf", ...). + scap_mode_t mode; ///< scap-mode required by the engine. + proc_entry_callback proc_callback; ///< Callback to be invoked for each thread/fd that is extracted from /proc, or NULL if no callback is needed. + void* proc_callback_context; ///< Opaque pointer that will be included in the calls to proc_callback. Ignored if proc_callback is NULL. + bool import_users; ///< true if the user list should be created when opening the capture. + const char* suppressed_comms[SCAP_MAX_SUPPRESSED_COMMS]; ///< A list of processes (comm) for which no + // events should be returned, with a trailing NULL value. + // You can provide additional comm + // values via scap_suppress_events_comm(). + interesting_ppm_sc_set ppm_sc_of_interest; ///< syscalls of interest. + interesting_tp_set tp_of_interest; ///< tp of interest. If left empty, no tracepoints will be attached + void* engine_params; ///< engine-specific params. + } scap_open_args; #ifdef __cplusplus } diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 5b682b00cf..7875b9e005 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -469,7 +469,7 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) } } -std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest) +std::unordered_set sinsp::enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest) { uint32_t *minimum_syscalls = scap_get_modifies_state_ppm_sc(); for (int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 888bfd24fa..55eaa56e60 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -832,9 +832,6 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source sinsp_parser* get_parser(); - // These make no sense on non-linux env -#ifdef __linux__ - /*! \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. Please note that this method must be called when the inspector is already open to @@ -854,7 +851,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source will always be up to date, or even work at all. */ std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = {}); -#endif + bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress); void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo); void add_meta_event(sinsp_evt *metaevt); From 9417dbb252ef3f55d3b5131838c4d3e841b84c4e Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Fri, 26 Aug 2022 16:41:27 +0200 Subject: [PATCH 16/29] fix(userspace): fix non-linux and modern-bpf builds. Signed-off-by: Federico Di Pierro --- userspace/libscap/CMakeLists.txt | 6 +++--- userspace/libscap/engine/modern_bpf/scap_modern_bpf.c | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/userspace/libscap/CMakeLists.txt b/userspace/libscap/CMakeLists.txt index ed9a48d460..631e789593 100644 --- a/userspace/libscap/CMakeLists.txt +++ b/userspace/libscap/CMakeLists.txt @@ -156,14 +156,14 @@ add_library(scap_event_schema syscall_info_table.c ../../driver/dynamic_params_table.c ../../driver/event_table.c - ../../driver/flags_table.c) + ../../driver/flags_table.c + ../../driver/tp_table.c) target_link_libraries(scap scap_event_schema) if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_library(driver_event_schema ../../driver/syscall_table.c - ../../driver/fillers_table.c - ../../driver/tp_table.c) + ../../driver/fillers_table.c) target_link_libraries(scap_event_schema driver_event_schema) endif() diff --git a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c index 19ef0c833f..8eb02a329c 100644 --- a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c +++ b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c @@ -67,9 +67,6 @@ static int32_t scap_modern_bpf__configure(struct scap_engine_handle engine, enum case SCAP_TRACERS_CAPTURE: /* Not supported */ return SCAP_SUCCESS; - case SCAP_PAGE_FAULTS: - /* Not supported */ - return SCAP_SUCCESS; case SCAP_SNAPLEN: pman_set_snaplen(arg1); case SCAP_EVENTMASK: @@ -78,9 +75,6 @@ static int32_t scap_modern_bpf__configure(struct scap_engine_handle engine, enum case SCAP_DYNAMIC_SNAPLEN: /* Not supported */ return SCAP_SUCCESS; - case SCAP_SIMPLEDRIVER_MODE: - /* Not supported */ - return SCAP_SUCCESS; case SCAP_FULLCAPTURE_PORT_RANGE: /* Not supported */ return SCAP_SUCCESS; From cb3ba23482450b09a1cc49caf035648e4e2a671a Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 26 Aug 2022 17:33:37 +0000 Subject: [PATCH 17/29] cleanup(libsinsp): remove unused API Signed-off-by: Andrea Terzolo --- userspace/libsinsp/sinsp.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 55eaa56e60..9719c16c64 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -889,7 +889,7 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source { enum ppm_event_flags flags = g_infotables.m_event_info[etype].flags; - return !(flags & sinsp::event_skip_flags()); + return !(flags & (EF_SKIPPARSERESET | EF_UNUSED)); } // Add comm to the list of comms for which the inspector @@ -938,12 +938,9 @@ VISIBILITY_PROTECTED m_mode = value; } +/// TODO: do we need this MACRO? VISIBILITY_PRIVATE - static inline ppm_event_flags event_skip_flags() - { - return (ppm_event_flags) (EF_SKIPPARSERESET | EF_UNUSED); - } // Doxygen doesn't understand VISIBILITY_PRIVATE #ifdef _DOXYGEN private: From 76f958144760954590194edccfdb9cadaf101d88 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Fri, 26 Aug 2022 17:51:12 +0000 Subject: [PATCH 18/29] cleanup(libsinsp): change signature of some methods Signed-off-by: Andrea Terzolo --- userspace/libsinsp/sinsp.cpp | 48 ++++++++++++++++++++++++------------ userspace/libsinsp/sinsp.h | 4 +-- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 7875b9e005..45c34e0411 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -482,14 +482,14 @@ std::unordered_set sinsp::enforce_sinsp_syscalls_of_interest(std::unor return syscalls_of_interest; } -void sinsp::fill_syscalls_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest) +void sinsp::fill_ppm_sc_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest) { - // Finally, set scap_open_args syscalls_of_interest for (int i = 0; i < PPM_SC_MAX; i++) { + /* If the set is empty, fallback to all interesting syscalls */ if (syscalls_of_interest.empty()) { - oargs->ppm_sc_of_interest.ppm_sc[i] = 1; + oargs->ppm_sc_of_interest.ppm_sc[i] = true; } else { @@ -500,7 +500,15 @@ void sinsp::fill_syscalls_of_interest(scap_open_args *oargs, const std::unordere void sinsp::fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest) { - if (!tp_of_interest.empty()) + /* If the set is empty, fallback to all interesting tracepoints */ + if (tp_of_interest.empty()) + { + for (int i = 0; i < TP_VAL_MAX; i++) + { + oargs->tp_of_interest.tp[i] = true; + } + } + else { for(const auto& tp : tp_of_interest) { @@ -512,17 +520,10 @@ void sinsp::fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set< oargs->tp_of_interest.tp[val] = true; } } - else - { - for (int i = 0; i < TP_VAL_MAX; i++) - { - oargs->tp_of_interest.tp[i] = true; - } - } } -void sinsp::open_common(scap_open_args* oargs, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) +void sinsp::open_common(scap_open_args* oargs) { char error[SCAP_LASTERR_SIZE] = {0}; g_logger.log("Trying to open the right engine!"); @@ -533,9 +534,6 @@ void sinsp::open_common(scap_open_args* oargs, const std::unordered_setmode; - fill_syscalls_of_interest(oargs, syscalls_of_interest); - fill_tp_of_interest(oargs, tp_of_interest); - if(!m_filter_proc_table_when_saving) { oargs->proc_callback = ::on_new_entry_from_proc; @@ -568,6 +566,12 @@ scap_open_args sinsp::factory_open_args(const char* engine_name, scap_mode_t sca void sinsp::open_kmod(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) { scap_open_args oargs = factory_open_args(KMOD_ENGINE, SCAP_MODE_LIVE); + + /* Set interesting syscalls and tracepoints. */ + fill_ppm_sc_of_interest(&oargs, syscalls_of_interest); + fill_tp_of_interest(&oargs, tp_of_interest); + + /* Engine-specific args. */ struct scap_kmod_engine_params params; params.single_buffer_dim = buffer_dimension; oargs.engine_params = ¶ms; @@ -583,6 +587,12 @@ void sinsp::open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std: } scap_open_args oargs = factory_open_args(BPF_ENGINE, SCAP_MODE_LIVE); + + /* Set interesting syscalls and tracepoints. */ + fill_ppm_sc_of_interest(&oargs, syscalls_of_interest); + fill_tp_of_interest(&oargs, tp_of_interest); + + /* Engine-specific args. */ struct scap_bpf_engine_params params; params.single_buffer_dim = buffer_dimension; params.bpf_probe = bpf_path; @@ -676,9 +686,15 @@ void sinsp::open_gvisor(std::string config_path, std::string root_path) set_get_procs_cpu_from_driver(false); } -void sinsp::open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interes) +void sinsp::open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) { scap_open_args oargs = factory_open_args(MODERN_BPF_ENGINE, SCAP_MODE_LIVE); + + /* Set interesting syscalls and tracepoints. */ + fill_ppm_sc_of_interest(&oargs, syscalls_of_interest); + fill_tp_of_interest(&oargs, tp_of_interest); + + /* Engine-specific args. */ struct scap_modern_bpf_engine_params params; params.single_buffer_dim = buffer_dimension; oargs.engine_params = ¶ms; diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index 9719c16c64..eb41cc8b2f 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -947,7 +947,7 @@ VISIBILITY_PRIVATE #endif void set_input_plugin(const string& name, const string& params); - void open_common(scap_open_args* oargs, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); + void open_common(scap_open_args* oargs); void init(); void deinit_state(); void consume_initialstate_events(); @@ -959,7 +959,7 @@ VISIBILITY_PRIVATE void remove_thread(int64_t tid, bool force); - void fill_syscalls_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest); + void fill_ppm_sc_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest); void fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest); // From 5db8905d0e08f127c791a785a3ac28d8f0bf44ce Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 27 Aug 2022 10:40:58 +0000 Subject: [PATCH 19/29] update(scap-open): add some `print` helpers Signed-off-by: Andrea Terzolo --- .../libscap/examples/01-open/scap_open.c | 127 +++++++++--------- 1 file changed, 64 insertions(+), 63 deletions(-) diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 72ae8b521d..5b56b64a11 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -54,11 +54,11 @@ bool ppm_sc_is_set; bool tp_is_set; /* Generic global variables. */ -scap_open_args oargs = {.engine_name = UNKNOWN_ENGINE}; /* scap oargs used in `scap_open`. */ -uint64_t g_nevts = 0; /* total number of events captured. */ -scap_t* g_h = NULL; /* global scap handler. */ -uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ -char* valptr = NULL; /* pointer used to print the value of event params. */ /* pointer used to print the value of event params. */ +scap_open_args oargs = {.engine_name = UNKNOWN_ENGINE}; /* scap oargs used in `scap_open`. */ +uint64_t g_nevts = 0; /* total number of events captured. */ +scap_t* g_h = NULL; /* global scap handler. */ +uint16_t* lens16 = NULL; /* pointer used to print the length of event params. */ +char* valptr = NULL; /* pointer used to print the value of event params. */ /* pointer used to print the value of event params. */ struct timeval tval_start, tval_end, tval_result; void enable_single_tp(const char* tp_basename) @@ -129,7 +129,6 @@ void set_enabled_syscalls() { oargs.ppm_sc_of_interest.ppm_sc[j] = true; } - } printf("------------------------------------------------------------------\n\n"); } @@ -434,102 +433,101 @@ void print_sorted_syscalls(char string_vector[SYSCALL_TABLE_SIZE][SYSCALL_NAME_M printf("Interesting syscalls: %d\n", dim); } -/* This are the real interesting syscalls that we want to support in the new probe. - * - all syscalls associated with events of type `UF_NEVER_DROP`. - * - * Please note: if some syscalls miss, probably, you have an old kernel - * that don't define them. Try to use a newer one. - */ -void print_modern_probe_syscalls() +void print_UF_NEVER_DROP_syscalls() { char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; int interesting_syscall = 0; - enum ppm_syscall_code ppm_syscall_code = 0; - /* For every syscall of the system. */ - for(int syscall_id = 0; syscall_id < SYSCALL_TABLE_SIZE; syscall_id++) + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - ppm_syscall_code = g_syscall_code_routing_table[syscall_id]; - - /* TAKE ALWAYS: If the syscall has `UF_NEVER_DROP` flag we cannot use simple consumer. */ - if(g_syscall_table[syscall_id].flags & UF_NEVER_DROP) + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - if(!g_syscall_info_table[ppm_syscall_code].name) + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) { - goto error; + continue; } - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_syscall_code].name); - continue; - } - /* TAKE NEVER: If we use generic events, we can drop the syscall with the simple consumer logic.*/ - if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E) - { - continue; + if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) + { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); + } } + } + + printf("\n------- Print UF_NEVER_DROP syscalls: \n"); + print_sorted_syscalls(str, interesting_syscall); +} + +void print_EF_MODIFIES_STATE_syscalls() +{ + char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; + int interesting_syscall = 0; - if(!g_syscall_info_table[ppm_syscall_code].name) + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - goto error; + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + { + continue; + } + + int enter_event = g_syscall_table[syscall_nr].enter_event_type; + if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) + { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); + } } - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_syscall_code].name); } + printf("\n------- Print EF_MODIFIES_STATE syscalls: \n"); print_sorted_syscalls(str, interesting_syscall); - return; - -error: - printf("unexpected error, please check with `%s` option", VALIDATION_OPTION); } -/* - * Print syscall supported by actual drivers: `KERNEL_MODULE`, `BPF_PROBE`. - */ -void print_actual_drivers_syscalls() +void print_both_syscalls() { char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; int interesting_syscall = 0; - for(int i = 0; i < PPM_SC_MAX; i++) + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - if(g_syscall_code_routing_table[syscall_nr] != i) + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + { + continue; + } + + if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); continue; } - if(oargs.ppm_sc_of_interest.ppm_sc[i] || g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) + int enter_event = g_syscall_table[syscall_nr].enter_event_type; + if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) { - strcpy(str[interesting_syscall++], g_syscall_info_table[i].name); + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); } } } + printf("\n------- Print 'EF_MODIFIES_STATE' and 'UF_NEVER_DROP' syscalls: \n"); print_sorted_syscalls(str, interesting_syscall); } -/* Print all supported syscall according to the scap source you have chosen: - * - `KERNEL_MODULE` or `BPF_PROBE`, print all syscalls supported by these - * sources - * - `MODERN_BPF_PROBE`, print all syscalls that will be supported by - * modern BPF probe. - * - `SCAP_FILE` not supported by this function. - */ void print_supported_syscalls() { - if(strncmp(oargs.engine_name, KMOD_ENGINE, KMOD_ENGINE_LEN) == 0 || - strncmp(oargs.engine_name, BPF_ENGINE, BPF_ENGINE_LEN) == 0) - { - print_actual_drivers_syscalls(); - } - else if(strncmp(oargs.engine_name, MODERN_BPF_ENGINE, MODERN_BPF_ENGINE_LEN) == 0) - { - print_modern_probe_syscalls(); - } - else + printf("\n------- Print supported syscalls: \n"); + + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - printf("Scap source not supported! Bye!"); + if(g_syscall_code_routing_table[syscall_nr] == PPM_SC_UNKNOWN) + { + continue; + } + int ppm_code = g_syscall_code_routing_table[syscall_nr]; + printf("- %-25s system_code: (%d) ppm_code: (%d)\n", g_syscall_info_table[ppm_code].name, syscall_nr, ppm_code); } } @@ -776,9 +774,13 @@ void parse_CLI_options(int argc, char** argv) if(!strcmp(argv[i], PRINT_SYSCALLS_OPTION)) { + print_UF_NEVER_DROP_syscalls(); + print_EF_MODIFIES_STATE_syscalls(); + print_both_syscalls(); print_supported_syscalls(); exit(EXIT_SUCCESS); } + if(!strcmp(argv[i], PRINT_HELP_OPTION)) { print_help(); @@ -882,7 +884,6 @@ int main(int argc, char** argv) continue; } } - if(res == SCAP_TIMEOUT || res == SCAP_FILTERED_EVENT) { continue; From 6155d52f18e6909b2517ed090ae6a620039f59f0 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 27 Aug 2022 11:03:49 +0000 Subject: [PATCH 20/29] update(libsinsp): remove `should_consider` API Signed-off-by: Andrea Terzolo --- userspace/libsinsp/event.cpp | 6 ------ userspace/libsinsp/event.h | 8 -------- 2 files changed, 14 deletions(-) diff --git a/userspace/libsinsp/event.cpp b/userspace/libsinsp/event.cpp index 039d633b9e..75ab87bead 100644 --- a/userspace/libsinsp/event.cpp +++ b/userspace/libsinsp/event.cpp @@ -2668,12 +2668,6 @@ scap_dump_flags sinsp_evt::get_dump_flags(OUT bool* should_drop) return (scap_dump_flags)dflags; } -bool sinsp_evt::should_consider() -{ - uint16_t etype = get_type(); - return sinsp::should_consider_evtnum(etype); -} - bool sinsp_evt::is_syscall_error() const { return (m_errorcode != 0) && diff --git a/userspace/libsinsp/event.h b/userspace/libsinsp/event.h index da8f08d61d..754925965e 100644 --- a/userspace/libsinsp/event.h +++ b/userspace/libsinsp/event.h @@ -340,14 +340,6 @@ class SINSP_PUBLIC sinsp_evt : public gen_event bool is_filtered_out(); scap_dump_flags get_dump_flags(OUT bool* should_drop); - /*! - \brief Return whether or not an event should be considered. (Generally, these events are - automatically filtered out, but some events related to internal tracking are - returned by next() anyway). - */ - - bool should_consider(); - inline uint16_t get_source() const override { return ESRC_SINSP; From 3a1b96836dfc541d09a8ab92aa891e401b484e19 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sat, 27 Aug 2022 14:51:35 +0000 Subject: [PATCH 21/29] cleanup(bpf-engine/kmod-engine): initialize tracepoints and syscalls Signed-off-by: Andrea Terzolo --- userspace/libscap/engine/bpf/bpf.h | 3 +- userspace/libscap/engine/bpf/scap_bpf.c | 38 +++++++++++----- userspace/libscap/engine/kmod/kmod.h | 4 ++ userspace/libscap/engine/kmod/scap_kmod.c | 55 ++++++++++++++++------- userspace/libscap/scap-int.h | 2 - userspace/libscap/scap.c | 24 +--------- userspace/libscap/scap_engine_util.c | 24 +++++++--- userspace/libscap/scap_engine_util.h | 26 ++++++++++- userspace/libsinsp/sinsp.cpp | 9 ++-- 9 files changed, 118 insertions(+), 67 deletions(-) diff --git a/userspace/libscap/engine/bpf/bpf.h b/userspace/libscap/engine/bpf/bpf.h index 5313c185b8..afaf8f1e23 100644 --- a/userspace/libscap/engine/bpf/bpf.h +++ b/userspace/libscap/engine/bpf/bpf.h @@ -34,7 +34,8 @@ limitations under the License. struct bpf_engine { struct scap_device_set m_dev_set; - bool *m_syscalls_of_interest; + bool syscalls_of_interest[SYSCALL_TABLE_SIZE]; + bool tracepoints_of_interest[TP_VAL_MAX]; size_t m_ncpus; char* m_lasterr; int m_bpf_prog_fds[BPF_PROGS_MAX]; diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 98a0c72224..82d74b383c 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -662,8 +662,7 @@ static bool is_tp_enabled(interesting_tp_set *tp_of_interest, const char *shname static int32_t load_bpf_file( struct bpf_engine *handle, const char *path, uint64_t *api_version_p, - uint64_t *schema_version_p, - interesting_tp_set *tp_of_interest) + uint64_t *schema_version_p) { int j; int maps_shndx = 0; @@ -821,7 +820,7 @@ static int32_t load_bpf_file( if(memcmp(shname, "tracepoint/", sizeof("tracepoint/") - 1) == 0 || memcmp(shname, "raw_tracepoint/", sizeof("raw_tracepoint/") - 1) == 0) { - if (is_tp_enabled(tp_of_interest, shname)) + if(is_tp_enabled(handle->tracepoints_of_interest, shname)) { if(load_tracepoint(handle, shname, data->d_buf, data->d_size) != SCAP_SUCCESS) { @@ -1423,8 +1422,7 @@ int32_t scap_bpf_load( struct bpf_engine *handle, const char *bpf_probe, uint64_t *api_version_p, - uint64_t *schema_version_p, - interesting_tp_set *tp_of_interest) + uint64_t *schema_version_p) { int online_cpu; int j; @@ -1443,7 +1441,7 @@ int32_t scap_bpf_load( return SCAP_FAILURE; } - if(load_bpf_file(handle, bpf_probe, api_version_p, schema_version_p, tp_of_interest) != SCAP_SUCCESS) + if(load_bpf_file(handle, bpf_probe, api_version_p, schema_version_p) != SCAP_SUCCESS) { return SCAP_FAILURE; } @@ -1633,8 +1631,22 @@ int32_t scap_bpf_get_n_tracepoint_hit(struct scap_engine_handle engine, long* re return SCAP_SUCCESS; } -int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) { +int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) +{ struct bpf_engine *handle = engine.m_handle; + if(SCAP_EVENTMASK_SET) + { + change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, true); + } + else + { + change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, false); + } + + /* We can have more than one syscall corresponding to the same `ppm_sc` for this + * reason we need to update again the entire table. As a future work every syscall + * must have is `PPM_SC_CODE`. + */ return populate_interesting_syscalls_map(handle); } @@ -1705,6 +1717,12 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) struct scap_bpf_engine_params *params = oargs->engine_params; strlcpy(bpf_probe_buf, params->bpf_probe, SCAP_MAX_PATH_SIZE); + /* During the initialization we copy the syscalls of interest and the + * tracepoints of interest from `scap_open_args` to the engine vectors. + */ + init_syscall_of_interest_table(oargs, engine.m_handle->syscalls_of_interest); + init_tracepoint_of_interest_table(oargs, engine.m_handle->tracepoints_of_interest); + // // Find out how many devices we have to open, which equals to the number of CPUs // @@ -1717,17 +1735,13 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) engine.m_handle->m_ncpus = num_cpus; - fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, handle->syscalls_of_interest); - // Make internal syscalls of interest point to scap_t syscalls of interest, to keep them updated - engine.m_handle->m_syscalls_of_interest = handle->syscalls_of_interest; - rc = devset_init(&engine.m_handle->m_dev_set, num_cpus, engine.m_handle->m_lasterr); if(rc != SCAP_SUCCESS) { return rc; } - rc = scap_bpf_load(engine.m_handle, bpf_probe_buf, &handle->m_api_version, &handle->m_schema_version, &oargs->tp_of_interest); + rc = scap_bpf_load(engine.m_handle, bpf_probe_buf, &handle->m_api_version, &handle->m_schema_version); if(rc != SCAP_SUCCESS) { return rc; diff --git a/userspace/libscap/engine/kmod/kmod.h b/userspace/libscap/engine/kmod/kmod.h index 5b6031c829..d17f0ba607 100644 --- a/userspace/libscap/engine/kmod/kmod.h +++ b/userspace/libscap/engine/kmod/kmod.h @@ -24,5 +24,9 @@ struct scap; struct kmod_engine { struct scap_device_set m_dev_set; + bool syscalls_of_interest[SYSCALL_TABLE_SIZE]; + bool tracepoints_of_interest[TP_VAL_MAX]; char* m_lasterr; }; + +#define SCAP_HANDLE_T struct kmod_engine diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index a6d76e32be..768ac4fc9c 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -76,15 +76,16 @@ static uint32_t get_max_consumers() int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) { - uint32_t j; - char filename[SCAP_MAX_PATH_SIZE]; - uint32_t ndevs; - int32_t rc; + uint32_t j = 0; + struct scap_engine_handle engine = handle->m_engine; + char filename[SCAP_MAX_PATH_SIZE] = {0}; + uint32_t ndevs = 0; + int32_t rc = 0; - int len; - uint32_t all_scanned_devs; - uint64_t api_version; - uint64_t schema_version; + int len = 0; + uint32_t all_scanned_devs = 0; + uint64_t api_version = 0; + uint64_t schema_version = 0; handle->m_ncpus = sysconf(_SC_NPROCESSORS_CONF); if(handle->m_ncpus == -1) @@ -103,20 +104,18 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) return SCAP_FAILURE; } - rc = devset_init(&handle->m_engine.m_handle->m_dev_set, ndevs, handle->m_lasterr); + rc = devset_init(&engine.m_handle->m_dev_set, ndevs, handle->m_lasterr); if(rc != SCAP_SUCCESS) { return rc; } - fill_syscalls_of_interest(&oargs->ppm_sc_of_interest, handle->syscalls_of_interest); - // // Allocate the device descriptors. // len = RING_BUF_SIZE * 2; - struct scap_device_set *devset = &handle->m_engine.m_handle->m_dev_set; + struct scap_device_set *devset = &engine.m_handle->m_dev_set; for(j = 0, all_scanned_devs = 0; j < devset->m_ndevs && all_scanned_devs < handle->m_ncpus; ++all_scanned_devs) { struct scap_device *dev = &devset->m_devs[j]; @@ -250,16 +249,25 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) ++j; } - // Set interesting syscalls, switching off any non-requested syscall + /* Here we copy the syscalls of interest and the + * tracepoints of interest from `scap_open_args` to the engine vectors. + */ + + /* Disable all not interesting syscalls */ for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) { - if (!handle->syscalls_of_interest[i]) + if(oargs->ppm_sc_of_interest.ppm_sc[i]) + { + scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_SET, g_syscall_code_routing_table[i]); + } + else { - scap_set_eventmask(handle, g_syscall_code_routing_table[i], false); + scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_UNSET, g_syscall_code_routing_table[i]); } } - // Set interesting Tracepoints + /* Set interesting Tracepoints */ + init_tracepoint_of_interest_table(oargs, engine.m_handle->tracepoints_of_interest); uint32_t tp_of_interest = 0; for (int i = 0; i < TP_VAL_MAX; i++) { @@ -467,8 +475,23 @@ int32_t scap_kmod_set_snaplen(struct scap_engine_handle engine, uint32_t snaplen return SCAP_SUCCESS; } +/// TODO: we need to pass directly the system syscall number not the `ppm_sc` here. int32_t scap_kmod_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) { + /* To be honest the kernel module doesn't have to keep in sync the kernel table with + * the userspace one, it would be enough to update the kernel one, but in case we want + * to know the actual state we have it. + */ + struct kmod_engine *handle = engine.m_handle; + if(SCAP_EVENTMASK_SET) + { + change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, true); + } + else + { + change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, false); + } + struct scap_device_set *devset = &engine.m_handle->m_dev_set; if (op != SCAP_EVENTMASK_ZERO) { diff --git a/userspace/libscap/scap-int.h b/userspace/libscap/scap-int.h index 7e7730d015..1aab807ce9 100644 --- a/userspace/libscap/scap-int.h +++ b/userspace/libscap/scap-int.h @@ -110,8 +110,6 @@ struct scap // matching an entry in m_suppressed_comms. uint64_t m_num_suppressed_evts; - bool syscalls_of_interest[SYSCALL_TABLE_SIZE]; - // API version supported by the driver // If the API version is unavailable for whatever reason, // it's equivalent to version 0.0.0 diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 36b924b23a..f2a8672580 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -107,7 +107,7 @@ scap_t* scap_open_udig_int(char *error, int32_t *rc, #ifndef _WIN32 scap_t* scap_open_live_int(char *error, int32_t *rc, scap_open_args* oargs) { - char filename[SCAP_MAX_PATH_SIZE]; + char filename[SCAP_MAX_PATH_SIZE] = {0}; scap_t* handle = NULL; // @@ -1355,28 +1355,6 @@ int64_t scap_get_readfile_offset(scap_t* handle) static int32_t scap_handle_eventmask(scap_t* handle, uint32_t op, uint32_t ppm_sc) { - switch(op) { - case SCAP_EVENTMASK_ZERO: - case SCAP_EVENTMASK_SET: - case SCAP_EVENTMASK_UNSET: - break; - - default: - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "%s(%d) internal error", __FUNCTION__, op); - ASSERT(false); - return SCAP_FAILURE; - break; - } - - // Keep syscalls of interest in sync - if (op != SCAP_EVENTMASK_ZERO) - { - set_syscall_of_interest(ppm_sc, handle->syscalls_of_interest, op == SCAP_EVENTMASK_SET); - } - else - { - memset(handle->syscalls_of_interest, 0, sizeof(handle->syscalls_of_interest)); - } if(handle->m_vtable) { return handle->m_vtable->configure(handle->m_engine, SCAP_EVENTMASK, op, ppm_sc); diff --git a/userspace/libscap/scap_engine_util.c b/userspace/libscap/scap_engine_util.c index d5b3eab0d8..86ecbf9b64 100644 --- a/userspace/libscap/scap_engine_util.c +++ b/userspace/libscap/scap_engine_util.c @@ -25,7 +25,7 @@ limitations under the License. #include "driver_config.h" #endif -void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable) +void change_interest_for_single_syscall(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable) { #ifdef __linux__ // We need to convert from PPM_SC to SYSCALL_NR, using the routing table @@ -35,19 +35,30 @@ void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool e if(g_syscall_code_routing_table[syscall_nr] == ppm_sc) { syscalls_of_interest[syscall_nr] = enable; - // DO NOT break as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) + // DO NOT use `break` here as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) } } #endif } -void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest) +void init_syscall_of_interest_table(scap_open_args *oargs, bool *syscalls_of_interest) { - for (int i = 0; i < PPM_SC_MAX; i++) + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - if (!ppm_sc_of_interest || ppm_sc_of_interest->ppm_sc[i]) + if(oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) { - set_syscall_of_interest(i, syscalls_of_interest, true); + change_interest_for_single_syscall(ppm_sc, syscalls_of_interest, true); + } + } +} + +void init_tracepoint_of_interest_table(scap_open_args *oargs, bool *tracepoints_of_interest) +{ + for(int t = 0; t < TP_VAL_MAX; t++) + { + if(oargs->tp_of_interest.tp[t]) + { + tracepoints_of_interest[t] = true; } } } @@ -81,4 +92,3 @@ int32_t check_api_compatibility(scap_t *handle, char *error) #endif return SCAP_SUCCESS; } - diff --git a/userspace/libscap/scap_engine_util.h b/userspace/libscap/scap_engine_util.h index 94dbce8846..ddec2a789e 100644 --- a/userspace/libscap/scap_engine_util.h +++ b/userspace/libscap/scap_engine_util.h @@ -17,6 +17,28 @@ limitations under the License. #pragma once -void set_syscall_of_interest(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable); -void fill_syscalls_of_interest(interesting_ppm_sc_set *ppm_sc_of_interest, bool *syscalls_of_interest); +void change_interest_for_single_syscall(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable); + +/** + * @brief Takes an array of `ppm_sc_code` from `scap_open_args` and set the + * interesting syscalls for a specific engine. + * + * Please note: This function must be used during the engine initialization. + * + * @param oargs pointer to the `scap_open_args` struct. + * @param syscalls_of_interest pointer to the engine syscalls of interest. + */ +void init_syscall_of_interest_table(scap_open_args *oargs, bool *syscalls_of_interest); + +/** + * @brief Takes an array of interesting tracepoints from `scap_open_args` and set the + * interesting tracepoints for a specific engine. + * + * Please note: This function must be used during the engine initialization. + * + * @param oargs pointer to the `scap_open_args` struct. + * @param tracepoints_of_interest pointer to the engine tracepoints of interest. + */ +void init_tracepoint_of_interest_table(scap_open_args *oargs, bool *tracepoints_of_interest) + int32_t check_api_compatibility(scap_t *handle, char *error); diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 45c34e0411..c0fe7cf216 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -452,17 +452,18 @@ void sinsp::set_import_users(bool import_users) m_usergroup_manager.m_import_users = import_users; } -void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enabled) +void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enable) { + /* This API must be used only after the initialization phase. */ if (!m_inited) { - throw sinsp_exception("you cannot used this method before opening the inspector."); + throw sinsp_exception("you cannot use this method before opening the inspector!"); } if (ppm_sc >= PPM_SC_MAX || ppm_sc < 0) { - throw sinsp_exception("unexistent ppm_sc code."); + throw sinsp_exception("unexistent ppm_sc code: " + std::to_string(ppm_sc)); } - int ret = scap_set_eventmask(m_h, ppm_sc, enabled); + int ret = scap_set_eventmask(m_h, ppm_sc, enable); if (ret != SCAP_SUCCESS) { throw sinsp_exception(scap_getlasterr(m_h)); From 340c0615b4ae86cb2455c5eeff3fdf658f739e03 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sun, 28 Aug 2022 11:47:34 +0000 Subject: [PATCH 22/29] refactor(libsinsp): use `uint32_t` instead of `string` for tracepoints Signed-off-by: Andrea Terzolo --- userspace/libscap/scap.c | 33 ++++++++++++--- userspace/libscap/scap.h | 7 ++- userspace/libsinsp/sinsp.cpp | 82 ++++++++++++++++++++++-------------- userspace/libsinsp/sinsp.h | 30 +++++++++---- 4 files changed, 106 insertions(+), 46 deletions(-) diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index f2a8672580..e3dfafbfe7 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1169,9 +1169,13 @@ int32_t scap_get_stats(scap_t* handle, OUT scap_stats* stats) return SCAP_SUCCESS; } -uint32_t *scap_get_modifies_state_ppm_sc() +int scap_get_modifies_state_ppm_sc(uint32_t* ppm_sc_array) { - static uint32_t minimum_ppm_sc_set[PPM_SC_MAX]; + if(ppm_sc_array == NULL) + { + return SCAP_FAILURE; + } + #ifdef __linux__ // Collect EF_MODIFIES_STATE events for (int i = 0; i < PPM_EVENT_MAX; i++) @@ -1183,7 +1187,7 @@ uint32_t *scap_get_modifies_state_ppm_sc() if (g_syscall_table[j].exit_event_type == i || g_syscall_table[j].enter_event_type == i) { uint32_t ppm_sc_code = g_syscall_code_routing_table[i]; - minimum_ppm_sc_set[ppm_sc_code] = 1; + ppm_sc_array[ppm_sc_code] = 1; } } } @@ -1195,11 +1199,30 @@ uint32_t *scap_get_modifies_state_ppm_sc() if (g_syscall_table[j].flags & UF_NEVER_DROP) { uint32_t ppm_sc_code = g_syscall_code_routing_table[j]; - minimum_ppm_sc_set[ppm_sc_code] = 1; + ppm_sc_array[ppm_sc_code] = 1; } } #endif - return minimum_ppm_sc_set; + return SCAP_SUCCESS; +} + +int scap_get_modifies_state_tracepoints(uint32_t* tp_array) +{ + if(tp_array == NULL) + { + return SCAP_FAILURE; + } + + tp_array[SYS_ENTER] = 1; + tp_array[SYS_EXIT] = 1; + tp_array[SCHED_SWITCH] = 1; + tp_array[SCHED_PROC_EXIT] = 1; + /* With `aarch64` and `s390x` we need also this, + * in `x86` they are not considered at all. + */ + tp_array[SCHED_PROC_EXEC] = 1; + tp_array[SCHED_PROC_EXEC] = 1; + return SCAP_SUCCESS; } // diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 8d44f7024e..d2f60179a5 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -833,7 +833,12 @@ int32_t scap_get_stats(scap_t* handle, OUT scap_stats* stats); /*! \brief Returns the set of ppm_sc whose events have EF_MODIFIES_STATE flag or whose syscall have UF_NEVER_DROP flag. */ -uint32_t *scap_get_modifies_state_ppm_sc(); +int scap_get_modifies_state_ppm_sc(uint32_t * ppm_sc_array); + +/*! + \brief Returns the set of minimum tracepoints required by `libsinsp` state. +*/ +int scap_get_modifies_state_tracepoints(uint32_t * tp_array); /*! \brief This function can be used to temporarily interrupt event capture. diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index c0fe7cf216..e6bac914d5 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -452,7 +452,7 @@ void sinsp::set_import_users(bool import_users) m_usergroup_manager.m_import_users = import_users; } -void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enable) +void sinsp::mark_ppm_sc_of_interest(uint32_t ppm_sc, bool enable) { /* This API must be used only after the initialization phase. */ if (!m_inited) @@ -470,58 +470,78 @@ void sinsp::mark_syscall_of_interest(uint32_t ppm_sc, bool enable) } } -std::unordered_set sinsp::enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest) +std::unordered_set sinsp::enforce_sinsp_state_ppm_sc(std::unordered_set ppm_sc_of_interest) { - uint32_t *minimum_syscalls = scap_get_modifies_state_ppm_sc(); - for (int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + std::vector minimum_syscalls; + minimum_syscalls.reserve(PPM_SC_MAX); + + /* Should never happen but just to be sure. */ + if(scap_get_modifies_state_ppm_sc(minimum_syscalls.data()) != SCAP_SUCCESS) + { + throw sinsp_exception("'minimum_syscalls' is an unexpected NULL vector!"); + } + + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + if(minimum_syscalls[ppm_sc]) + { + ppm_sc_of_interest.insert(ppm_sc); + } + } + return ppm_sc_of_interest; +} + +std::unordered_set sinsp::enforce_sinsp_state_tracepoints(std::unordered_set tp_of_interest) +{ + std::vector minimum_tracepoints; + minimum_tracepoints.reserve(TP_VAL_MAX); + + /* Should never happen but just to be sure. */ + if(scap_get_modifies_state_tracepoints(minimum_tracepoints.data()) != SCAP_SUCCESS) + { + throw sinsp_exception("'minimum_tracepoints' is an unexpected NULL vector!"); + } + + for(int tp = 0; tp < TP_VAL_MAX; tp++) { - if (minimum_syscalls[ppm_sc]) + if(minimum_tracepoints[tp]) { - syscalls_of_interest.insert(ppm_sc); + tp_of_interest.insert(tp); } } - return syscalls_of_interest; + return tp_of_interest; } -void sinsp::fill_ppm_sc_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest) +void sinsp::fill_ppm_sc_of_interest(scap_open_args *oargs, const std::unordered_set &ppm_sc_of_interest) { for (int i = 0; i < PPM_SC_MAX; i++) { /* If the set is empty, fallback to all interesting syscalls */ - if (syscalls_of_interest.empty()) + if (ppm_sc_of_interest.empty()) { oargs->ppm_sc_of_interest.ppm_sc[i] = true; } else { - oargs->ppm_sc_of_interest.ppm_sc[i] = syscalls_of_interest.find(i) != syscalls_of_interest.end(); + oargs->ppm_sc_of_interest.ppm_sc[i] = ppm_sc_of_interest.find(i) != ppm_sc_of_interest.end(); } } } -void sinsp::fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest) +void sinsp::fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest) { - /* If the set is empty, fallback to all interesting tracepoints */ - if (tp_of_interest.empty()) + for(int i = 0; i < TP_VAL_MAX; i++) { - for (int i = 0; i < TP_VAL_MAX; i++) + /* If the set is empty, fallback to all interesting tracepoints */ + if (tp_of_interest.empty()) { oargs->tp_of_interest.tp[i] = true; } - } - else - { - for(const auto& tp : tp_of_interest) + else { - auto val = (uint32_t)tp_from_name(tp.c_str()); - if(val == -1) - { - throw sinsp_exception("unexisting tracepoint " + tp); - } - oargs->tp_of_interest.tp[val] = true; + oargs->tp_of_interest.tp[i] = tp_of_interest.find(i) != tp_of_interest.end(); } } - } void sinsp::open_common(scap_open_args* oargs) @@ -564,12 +584,12 @@ scap_open_args sinsp::factory_open_args(const char* engine_name, scap_mode_t sca return oargs; } -void sinsp::open_kmod(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) +void sinsp::open_kmod(uint64_t buffer_dimension, const std::unordered_set &ppm_sc_of_interest, const std::unordered_set &tp_of_interest) { scap_open_args oargs = factory_open_args(KMOD_ENGINE, SCAP_MODE_LIVE); /* Set interesting syscalls and tracepoints. */ - fill_ppm_sc_of_interest(&oargs, syscalls_of_interest); + fill_ppm_sc_of_interest(&oargs, ppm_sc_of_interest); fill_tp_of_interest(&oargs, tp_of_interest); /* Engine-specific args. */ @@ -580,7 +600,7 @@ void sinsp::open_kmod(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) +void sinsp::open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std::unordered_set &ppm_sc_of_interest, const std::unordered_set &tp_of_interest) { if(!bpf_path) { @@ -590,7 +610,7 @@ void sinsp::open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std: scap_open_args oargs = factory_open_args(BPF_ENGINE, SCAP_MODE_LIVE); /* Set interesting syscalls and tracepoints. */ - fill_ppm_sc_of_interest(&oargs, syscalls_of_interest); + fill_ppm_sc_of_interest(&oargs, ppm_sc_of_interest); fill_tp_of_interest(&oargs, tp_of_interest); /* Engine-specific args. */ @@ -687,12 +707,12 @@ void sinsp::open_gvisor(std::string config_path, std::string root_path) set_get_procs_cpu_from_driver(false); } -void sinsp::open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest, const std::unordered_set &tp_of_interest) +void sinsp::open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &ppm_sc_of_interest, const std::unordered_set &tp_of_interest) { scap_open_args oargs = factory_open_args(MODERN_BPF_ENGINE, SCAP_MODE_LIVE); /* Set interesting syscalls and tracepoints. */ - fill_ppm_sc_of_interest(&oargs, syscalls_of_interest); + fill_ppm_sc_of_interest(&oargs, ppm_sc_of_interest); fill_tp_of_interest(&oargs, tp_of_interest); /* Engine-specific args. */ diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index eb41cc8b2f..d31d73badd 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -219,14 +219,14 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source /* Wrappers to open a specific engine. */ - void open_kmod(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); - void open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); + void open_kmod(uint64_t buffer_dimension, const std::unordered_set &ppm_sc_of_interest = {}, const std::unordered_set &tp_of_interest = {}); + void open_bpf(uint64_t buffer_dimension, const char* bpf_path, const std::unordered_set &ppm_sc_of_interest = {}, const std::unordered_set &tp_of_interest = {}); void open_udig(); void open_nodriver(); void open_savefile(const std::string &filename, int fd); void open_plugin(std::string plugin_name, std::string plugin_open_params); void open_gvisor(std::string config_path, std::string root_path); - void open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &syscalls_of_interest = {}, const std::unordered_set &tp_of_interest = {}); + void open_modern_bpf(uint64_t buffer_dimension, const std::unordered_set &ppm_sc_of_interest = {}, const std::unordered_set &tp_of_interest = {}); void open_test_input(scap_test_input_data *data); scap_open_args factory_open_args(const char* engine, scap_mode_t scap_mode); @@ -834,23 +834,36 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source /*! \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. + This method receives a `ppm_sc` code, not a syscall system code, the same ppm_code + can match more than one system syscall. Please note that this method must be called when the inspector is already open to modify at runtime the interesting syscall set. WARNING: playing with this API could break `libsinsp` state collection, this is only useful in advanced cases where the client needs to know what it is doing! */ - void mark_syscall_of_interest(uint32_t ppm_sc, bool enabled = true); + void mark_ppm_sc_of_interest(uint32_t ppm_sc, bool enabled = true); /*! - \brief Provide the minimum set of syscalls required by sinsp state collection. + \brief Provide the minimum set of syscalls required by `libsinsp` state collection. If you call it without arguments it returns a new set with just these syscalls otherwise, it merges the minimum set of syscalls with the one you provided. WARNING: without using this method, we cannot guarantee that `libsinsp` state will always be up to date, or even work at all. */ - std::unordered_set enforce_sinsp_syscalls_of_interest(std::unordered_set syscalls_of_interest = {}); + std::unordered_set enforce_sinsp_state_ppm_sc(std::unordered_set ppm_sc_of_interest = {}); + + /*! + \brief Provide the minimum set of tracepoints required by `libsinsp` state collection. + If you call it without arguments it returns a new set with just these tracepoints + otherwise, it merges the minimum set of tracepoints with the one you provided. + + WARNING: without using this method, we cannot guarantee that `libsinsp` state + will always be up to date, or even work at all. + */ + std::unordered_set enforce_sinsp_state_tracepoints(std::unordered_set tp_of_interest = {}); + bool setup_cycle_writer(std::string base_file_name, int rollover_mb, int duration_seconds, int file_limit, unsigned long event_limit, bool compress); void import_ipv4_interface(const sinsp_ipv4_ifinfo& ifinfo); @@ -956,11 +969,10 @@ VISIBILITY_PRIVATE void import_ifaddr_list(); void import_user_list(); void add_protodecoders(); - void remove_thread(int64_t tid, bool force); - void fill_ppm_sc_of_interest(scap_open_args *oargs, const std::unordered_set &syscalls_of_interest); - void fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest); + void fill_ppm_sc_of_interest(scap_open_args *oargs, const std::unordered_set &ppm_sc_of_interest); + void fill_tp_of_interest(scap_open_args *oargs, const std::unordered_set &tp_of_interest); // // Note: lookup_only should be used when the query for the thread is made From f6429637d4b19c53528e2aa4674f4f029da23535 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sun, 28 Aug 2022 13:35:27 +0000 Subject: [PATCH 23/29] cleanup(bpf-engine/kmod-engine): remove unused tables from the engines Signed-off-by: Andrea Terzolo --- driver/main.c | 1 + userspace/libscap/engine/bpf/bpf.h | 2 - userspace/libscap/engine/bpf/scap_bpf.c | 78 +++++++++++++---------- userspace/libscap/engine/kmod/kmod.h | 2 - userspace/libscap/engine/kmod/scap_kmod.c | 21 +----- userspace/libscap/scap_engine_util.c | 38 ----------- userspace/libscap/scap_engine_util.h | 24 ------- 7 files changed, 46 insertions(+), 120 deletions(-) diff --git a/driver/main.c b/driver/main.c index 688a8076ca..72f8b92fc2 100644 --- a/driver/main.c +++ b/driver/main.c @@ -648,6 +648,7 @@ static int force_tp_set(u32 new_tp_set, u32 max_val) for(idx = 0; idx < max_val && ret == 0; idx++) { + ret = 0; new_val = new_tp_set & (1 << idx); curr_val = g_tracepoints_attached & (1 << idx); if((new_val ^ curr_val) == 0) diff --git a/userspace/libscap/engine/bpf/bpf.h b/userspace/libscap/engine/bpf/bpf.h index afaf8f1e23..3352991d60 100644 --- a/userspace/libscap/engine/bpf/bpf.h +++ b/userspace/libscap/engine/bpf/bpf.h @@ -34,8 +34,6 @@ limitations under the License. struct bpf_engine { struct scap_device_set m_dev_set; - bool syscalls_of_interest[SYSCALL_TABLE_SIZE]; - bool tracepoints_of_interest[TP_VAL_MAX]; size_t m_ncpus; char* m_lasterr; int m_bpf_prog_fds[BPF_PROGS_MAX]; diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 82d74b383c..9d25959774 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -662,7 +662,8 @@ static bool is_tp_enabled(interesting_tp_set *tp_of_interest, const char *shname static int32_t load_bpf_file( struct bpf_engine *handle, const char *path, uint64_t *api_version_p, - uint64_t *schema_version_p) + uint64_t *schema_version_p, + scap_open_args *oargs) { int j; int maps_shndx = 0; @@ -820,7 +821,7 @@ static int32_t load_bpf_file( if(memcmp(shname, "tracepoint/", sizeof("tracepoint/") - 1) == 0 || memcmp(shname, "raw_tracepoint/", sizeof("raw_tracepoint/") - 1) == 0) { - if(is_tp_enabled(handle->tracepoints_of_interest, shname)) + if(is_tp_enabled(&(oargs->tp_of_interest), shname)) { if(load_tracepoint(handle, shname, data->d_buf, data->d_size) != SCAP_SUCCESS) { @@ -919,13 +920,13 @@ static int32_t populate_syscall_table_map(struct bpf_engine *handle) return bpf_map_freeze(handle->m_bpf_map_fds[SCAP_SYSCALL_TABLE]); } -static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle) +static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle, scap_open_args *oargs) { int j; for(j = 0; j < SYSCALL_TABLE_SIZE; ++j) { - if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &j, &handle->m_syscalls_of_interest[j], BPF_ANY) != 0) + if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &j, &(oargs->m_syscalls_of_interest[j]), BPF_ANY) != 0) { snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_INTERESTING_SYSCALLS_TABLE bpf_map_update_elem < 0"); return SCAP_FAILURE; @@ -935,6 +936,39 @@ static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle) return SCAP_SUCCESS; } +static int32_t update_interesting_syscalls_map(struct scap_engine_handle *engine, uint32_t op, uint32_t ppm_sc) +{ + struct bpf_engine *handle = engine->m_handle; + bool enable; + if(op == SCAP_EVENTMASK_SET) + { + enable = true; + } + else + { + enable = false; + } + + /* We can have more than one syscall corresponding to the same `ppm_sc` for this + * reason we need to check the entire table. As a future work every syscall + * must have is `PPM_SC_CODE`. + */ + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + { + continue; + } + + if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &syscall_nr, &enable, BPF_ANY) != 0) + { + snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_INTERESTING_SYSCALLS_TABLE unable to update syscall: %d", syscall_nr); + return SCAP_FAILURE; + } + } + return SCAP_SUCCESS; +} + static int32_t populate_event_table_map(struct bpf_engine *handle) { int j; @@ -1422,7 +1456,8 @@ int32_t scap_bpf_load( struct bpf_engine *handle, const char *bpf_probe, uint64_t *api_version_p, - uint64_t *schema_version_p) + uint64_t *schema_version_p, + scap_open_args *oargs) { int online_cpu; int j; @@ -1441,7 +1476,7 @@ int32_t scap_bpf_load( return SCAP_FAILURE; } - if(load_bpf_file(handle, bpf_probe, api_version_p, schema_version_p) != SCAP_SUCCESS) + if(load_bpf_file(handle, bpf_probe, api_version_p, schema_version_p, oargs) != SCAP_SUCCESS) { return SCAP_FAILURE; } @@ -1456,7 +1491,7 @@ int32_t scap_bpf_load( return SCAP_FAILURE; } - if(populate_interesting_syscalls_map(handle) != SCAP_SUCCESS) + if(populate_interesting_syscalls_map(handle, oargs) != SCAP_SUCCESS) { return SCAP_FAILURE; } @@ -1631,25 +1666,6 @@ int32_t scap_bpf_get_n_tracepoint_hit(struct scap_engine_handle engine, long* re return SCAP_SUCCESS; } -int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) -{ - struct bpf_engine *handle = engine.m_handle; - if(SCAP_EVENTMASK_SET) - { - change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, true); - } - else - { - change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, false); - } - - /* We can have more than one syscall corresponding to the same `ppm_sc` for this - * reason we need to update again the entire table. As a future work every syscall - * must have is `PPM_SC_CODE`. - */ - return populate_interesting_syscalls_map(handle); -} - static int32_t next(struct scap_engine_handle engine, OUT scap_evt** pevent, OUT uint16_t* pcpuid) { return ringbuffer_next(&engine.m_handle->m_dev_set, pevent, pcpuid); @@ -1685,7 +1701,7 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set case SCAP_SNAPLEN: return scap_bpf_set_snaplen(engine, arg1); case SCAP_EVENTMASK: - return scap_bpf_handle_event_mask(engine, arg1, arg2); + return update_interesting_syscalls_map(engine, arg1, arg2); case SCAP_DYNAMIC_SNAPLEN: if(arg1 == 0) { @@ -1717,12 +1733,6 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) struct scap_bpf_engine_params *params = oargs->engine_params; strlcpy(bpf_probe_buf, params->bpf_probe, SCAP_MAX_PATH_SIZE); - /* During the initialization we copy the syscalls of interest and the - * tracepoints of interest from `scap_open_args` to the engine vectors. - */ - init_syscall_of_interest_table(oargs, engine.m_handle->syscalls_of_interest); - init_tracepoint_of_interest_table(oargs, engine.m_handle->tracepoints_of_interest); - // // Find out how many devices we have to open, which equals to the number of CPUs // @@ -1741,7 +1751,7 @@ static int32_t init(scap_t* handle, scap_open_args *oargs) return rc; } - rc = scap_bpf_load(engine.m_handle, bpf_probe_buf, &handle->m_api_version, &handle->m_schema_version); + rc = scap_bpf_load(engine.m_handle, bpf_probe_buf, &handle->m_api_version, &handle->m_schema_version, oargs); if(rc != SCAP_SUCCESS) { return rc; diff --git a/userspace/libscap/engine/kmod/kmod.h b/userspace/libscap/engine/kmod/kmod.h index d17f0ba607..5f48b978e2 100644 --- a/userspace/libscap/engine/kmod/kmod.h +++ b/userspace/libscap/engine/kmod/kmod.h @@ -24,8 +24,6 @@ struct scap; struct kmod_engine { struct scap_device_set m_dev_set; - bool syscalls_of_interest[SYSCALL_TABLE_SIZE]; - bool tracepoints_of_interest[TP_VAL_MAX]; char* m_lasterr; }; diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index 768ac4fc9c..036eafcffe 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -249,11 +249,7 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) ++j; } - /* Here we copy the syscalls of interest and the - * tracepoints of interest from `scap_open_args` to the engine vectors. - */ - - /* Disable all not interesting syscalls */ + /* Set interesting Syscalls */ for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) { if(oargs->ppm_sc_of_interest.ppm_sc[i]) @@ -267,7 +263,6 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) } /* Set interesting Tracepoints */ - init_tracepoint_of_interest_table(oargs, engine.m_handle->tracepoints_of_interest); uint32_t tp_of_interest = 0; for (int i = 0; i < TP_VAL_MAX; i++) { @@ -478,20 +473,6 @@ int32_t scap_kmod_set_snaplen(struct scap_engine_handle engine, uint32_t snaplen /// TODO: we need to pass directly the system syscall number not the `ppm_sc` here. int32_t scap_kmod_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) { - /* To be honest the kernel module doesn't have to keep in sync the kernel table with - * the userspace one, it would be enough to update the kernel one, but in case we want - * to know the actual state we have it. - */ - struct kmod_engine *handle = engine.m_handle; - if(SCAP_EVENTMASK_SET) - { - change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, true); - } - else - { - change_interest_for_single_syscall(ppm_sc, handle->syscalls_of_interest, false); - } - struct scap_device_set *devset = &engine.m_handle->m_dev_set; if (op != SCAP_EVENTMASK_ZERO) { diff --git a/userspace/libscap/scap_engine_util.c b/userspace/libscap/scap_engine_util.c index 86ecbf9b64..fcc2113eda 100644 --- a/userspace/libscap/scap_engine_util.c +++ b/userspace/libscap/scap_engine_util.c @@ -25,44 +25,6 @@ limitations under the License. #include "driver_config.h" #endif -void change_interest_for_single_syscall(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable) -{ -#ifdef __linux__ - // We need to convert from PPM_SC to SYSCALL_NR, using the routing table - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) - { - // Find the match between the ppm_sc and the syscall_nr - if(g_syscall_code_routing_table[syscall_nr] == ppm_sc) - { - syscalls_of_interest[syscall_nr] = enable; - // DO NOT use `break` here as some PPM_SC are used multiple times for different syscalls! (eg: PPM_SC_SETRESUID...) - } - } -#endif -} - -void init_syscall_of_interest_table(scap_open_args *oargs, bool *syscalls_of_interest) -{ - for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) - { - if(oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) - { - change_interest_for_single_syscall(ppm_sc, syscalls_of_interest, true); - } - } -} - -void init_tracepoint_of_interest_table(scap_open_args *oargs, bool *tracepoints_of_interest) -{ - for(int t = 0; t < TP_VAL_MAX; t++) - { - if(oargs->tp_of_interest.tp[t]) - { - tracepoints_of_interest[t] = true; - } - } -} - int32_t check_api_compatibility(scap_t *handle, char *error) { #ifdef PPM_API_CURRENT_VERSION_MAJOR diff --git a/userspace/libscap/scap_engine_util.h b/userspace/libscap/scap_engine_util.h index ddec2a789e..48c1e95349 100644 --- a/userspace/libscap/scap_engine_util.h +++ b/userspace/libscap/scap_engine_util.h @@ -17,28 +17,4 @@ limitations under the License. #pragma once -void change_interest_for_single_syscall(uint32_t ppm_sc, bool *syscalls_of_interest, bool enable); - -/** - * @brief Takes an array of `ppm_sc_code` from `scap_open_args` and set the - * interesting syscalls for a specific engine. - * - * Please note: This function must be used during the engine initialization. - * - * @param oargs pointer to the `scap_open_args` struct. - * @param syscalls_of_interest pointer to the engine syscalls of interest. - */ -void init_syscall_of_interest_table(scap_open_args *oargs, bool *syscalls_of_interest); - -/** - * @brief Takes an array of interesting tracepoints from `scap_open_args` and set the - * interesting tracepoints for a specific engine. - * - * Please note: This function must be used during the engine initialization. - * - * @param oargs pointer to the `scap_open_args` struct. - * @param tracepoints_of_interest pointer to the engine tracepoints of interest. - */ -void init_tracepoint_of_interest_table(scap_open_args *oargs, bool *tracepoints_of_interest) - int32_t check_api_compatibility(scap_t *handle, char *error); From d9e19008528b06ca75b7016a8789e6dcbb9c451a Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sun, 28 Aug 2022 17:22:25 +0000 Subject: [PATCH 24/29] fix(libscap/libsinsp): allow examples to work correctly Signed-off-by: Andrea Terzolo --- userspace/libscap/engine/bpf/scap_bpf.c | 64 +++++---- userspace/libscap/engine/kmod/kmod.h | 2 - userspace/libscap/engine/kmod/scap_kmod.c | 8 +- userspace/libscap/examples/01-open/README.md | 49 +++++-- .../libscap/examples/01-open/scap_open.c | 121 +++++++++--------- userspace/libscap/scap.c | 4 +- userspace/libsinsp/examples/test.cpp | 72 +++++------ userspace/libsinsp/sinsp.cpp | 8 +- 8 files changed, 181 insertions(+), 147 deletions(-) diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 9d25959774..44c4f722f5 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -920,55 +920,65 @@ static int32_t populate_syscall_table_map(struct bpf_engine *handle) return bpf_map_freeze(handle->m_bpf_map_fds[SCAP_SYSCALL_TABLE]); } -static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle, scap_open_args *oargs) +static int32_t set_single_syscall_of_interest(struct bpf_engine *handle, int ppm_sc, bool value) { - int j; - - for(j = 0; j < SYSCALL_TABLE_SIZE; ++j) + /* We can have more than one syscall corresponding to the same `ppm_sc` for this + * reason we need to check the entire table. As a future work every syscall + * must have is `PPM_SC_CODE`. + */ + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &j, &(oargs->m_syscalls_of_interest[j]), BPF_ANY) != 0) + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) { - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_INTERESTING_SYSCALLS_TABLE bpf_map_update_elem < 0"); + continue; + } + + if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &syscall_nr, &value, BPF_ANY) != 0) + { + snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_INTERESTING_SYSCALLS_TABLE unable to update syscall: %d", syscall_nr); return SCAP_FAILURE; } } - return SCAP_SUCCESS; } -static int32_t update_interesting_syscalls_map(struct scap_engine_handle *engine, uint32_t op, uint32_t ppm_sc) +static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle, scap_open_args *oargs) { - struct bpf_engine *handle = engine->m_handle; bool enable; - if(op == SCAP_EVENTMASK_SET) - { - enable = true; - } - else - { - enable = false; - } - - /* We can have more than one syscall corresponding to the same `ppm_sc` for this - * reason we need to check the entire table. As a future work every syscall - * must have is `PPM_SC_CODE`. - */ - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + if(oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) { - continue; + enable = true; + } + else + { + enable = false; } - if(bpf_map_update_elem(handle->m_bpf_map_fds[SCAP_INTERESTING_SYSCALLS_TABLE], &syscall_nr, &enable, BPF_ANY) != 0) + if(set_single_syscall_of_interest(handle, ppm_sc, enable) != SCAP_SUCCESS) { - snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "SCAP_INTERESTING_SYSCALLS_TABLE unable to update syscall: %d", syscall_nr); return SCAP_FAILURE; } } return SCAP_SUCCESS; } +static int32_t update_interesting_syscalls_map(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) +{ + struct bpf_engine *handle = engine.m_handle; + bool enable; + if(op == SCAP_EVENTMASK_SET) + { + enable = true; + } + else + { + enable = false; + } + return set_single_syscall_of_interest(handle, ppm_sc, enable); +} + static int32_t populate_event_table_map(struct bpf_engine *handle) { int j; diff --git a/userspace/libscap/engine/kmod/kmod.h b/userspace/libscap/engine/kmod/kmod.h index 5f48b978e2..5b6031c829 100644 --- a/userspace/libscap/engine/kmod/kmod.h +++ b/userspace/libscap/engine/kmod/kmod.h @@ -26,5 +26,3 @@ struct kmod_engine struct scap_device_set m_dev_set; char* m_lasterr; }; - -#define SCAP_HANDLE_T struct kmod_engine diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index 036eafcffe..a0135d2e6c 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -250,15 +250,15 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) } /* Set interesting Syscalls */ - for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - if(oargs->ppm_sc_of_interest.ppm_sc[i]) + if(oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) { - scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_SET, g_syscall_code_routing_table[i]); + scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_SET, ppm_sc); } else { - scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_UNSET, g_syscall_code_routing_table[i]); + scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_UNSET, ppm_sc); } } diff --git a/userspace/libscap/examples/01-open/README.md b/userspace/libscap/examples/01-open/README.md index 80b6ad338e..72748933da 100644 --- a/userspace/libscap/examples/01-open/README.md +++ b/userspace/libscap/examples/01-open/README.md @@ -27,7 +27,8 @@ You can enable them with the following options: For each `scap` source you can set additional configurations: ``` -'--simple_consumer': enable the simple consumer mode. (default: disabled) +'--tp ': enable only requested tracepoint. Can be passed multiple times. (dafault: all enabled) +'--ppm_sc ': enable only requested syscall (this is our internal ppm syscall code not the system syscall code). Can be passed multiple times. (dafault: all enabled) '--num_events ': number of events to catch before terminating. (default: UINT64_MAX) '--evt_type ': every event of this type will be printed to console. (default: -1, no print) ``` @@ -100,12 +101,27 @@ As soon as you quit (`CTRL-C`) the `scap-open` program, you will be prompted wit ``` ---------------------- STATS ----------------------- -events captured: 39460 -seen by driver: 39912 +Events captured: 20 +Seen by driver: 20 +Time elapsed: 2 s +Number of events/per-second: 10 Number of dropped events: 0 -Number of dropped events caused by full buffer: 0 -Number of dropped events caused by invalid memory access: 0 -Number of dropped events caused by an invalid condition in the kernel instrumentation: 0 +Number of dropped events caused by full buffer (total / all buffer drops - includes all categories below, likely higher than sum of syscall categories): 0 +Number of dropped events caused by full buffer (n_drops_buffer_clone_fork_enter syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_clone_fork_exit syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_execve_enter syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_execve_exit syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_connect_enter syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_connect_exit syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_open_enter syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_open_exit syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_dir_file_enter syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_dir_file_exit syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_other_interest_enter syscall category): 0 +Number of dropped events caused by full buffer (n_drops_buffer_other_interest_exit syscall category): 0 +Number of dropped events caused by full scratch map: 0 +Number of dropped events caused by invalid memory access (page faults): 0 +Number of dropped events caused by an invalid condition in the kernel instrumentation (bug): 0 Number of preemptions: 0 Number of events skipped due to the tid being in a set of suppressed tids: 0 Number of threads currently being suppressed: 0 @@ -114,7 +130,7 @@ Number of threads currently being suppressed: 0 To run it with the kernel module, you first have to inject the kernel module into the kernel: -``` +```bash sudo insmod driver/scap.ko ``` @@ -152,14 +168,25 @@ Here there are just some examples: sudo ./libscap/examples/01-open/scap-open --scap_file ~/my_scap_file/path ``` -- Use BPF probe in simple consumer mode, print all events with type `80` and catch at most `898898` events. +- Use BPF probe with only `mkdir` syscall and `sys_enter` tracepoint (on x86_64 architecture) + +1. Check the `ppm_code` of `mkdir`, the code is `27` as you can see: + +```bash +sudo ./libscap/examples/01-open/scap-open --ppm_sc | grep mkdir +- mkdir system_code: (83) ppm_code: (27) +- mkdirat system_code: (258) ppm_code: (198) +``` + +2. Check the code for `sys_enter` tracepoint, the code is `0` as you can see: ```bash -sudo ./libscap/examples/01-open/scap-open --bpf driver/bpf/probe.o --simple_consumer --evt_type 80 --num_events 898898 +sudo ./libscap/examples/01-open/scap-open --tp | grep sys_enter +- sys_enter tp_code: (0) ``` -- Print all supported syscall in simple consumer mode by the kernel module. +3. Run the command with the obtained configuration: ```bash -sudo ./libscap/examples/01-open/scap-open --kmod --simple_consumer --print_syscalls +sudo ./libscap/examples/01-open/scap-open --bpf driver/bpf/probe.o --ppm_sc 27 --tp 0 ``` diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 5b56b64a11..dc4153d036 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -22,36 +22,40 @@ limitations under the License. #include #include +#define SYSCALL_NAME_MAX_LEN 40 +#define UNKNOWN_ENGINE "unknown" + +/* SCAP SOURCES */ #define KMOD_OPTION "--kmod" #define BPF_OPTION "--bpf" #define MODERN_BPF_OPTION "--modern_bpf" #define SCAP_FILE_OPTION "--scap_file" + +/* CONFIGURATIONS */ #define TP_OPTION "--tp" #define PPM_SC_OPTION "--ppm_sc" #define NUM_EVENTS_OPTION "--num_events" #define EVENT_TYPE_OPTION "--evt_type" + +/* PRINT */ #define VALIDATION_OPTION "--validate_syscalls" #define PRINT_SYSCALLS_OPTION "--print_syscalls" #define PRINT_HELP_OPTION "--help" -#define SYSCALL_NAME_MAX_LEN 40 -#define UNKNOWN_ENGINE "unknown" -#define UNKNOWN_ENGINE_LEN 7 - extern const struct ppm_syscall_desc g_syscall_info_table[PPM_SC_MAX]; extern const struct ppm_event_info g_event_info[PPM_EVENT_MAX]; extern const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE]; extern const enum ppm_syscall_code g_syscall_code_routing_table[SYSCALL_TABLE_SIZE]; /* Engine params */ -struct scap_bpf_engine_params bpf_params; -struct scap_savefile_engine_params savefile_params; +struct scap_bpf_engine_params bpf_params = {0}; +struct scap_savefile_engine_params savefile_params = {0}; /* Configuration variables set through CLI. */ uint64_t num_events = UINT64_MAX; /* max number of events to catch. */ int evt_type = -1; /* event type to print. */ -bool ppm_sc_is_set; -bool tp_is_set; +bool ppm_sc_is_set = 0; +bool tp_is_set = 0; /* Generic global variables. */ scap_open_args oargs = {.engine_name = UNKNOWN_ENGINE}; /* scap oargs used in `scap_open`. */ @@ -61,33 +65,23 @@ uint16_t* lens16 = NULL; /* pointer used to print the length of event p char* valptr = NULL; /* pointer used to print the value of event params. */ /* pointer used to print the value of event params. */ struct timeval tval_start, tval_end, tval_result; -void enable_single_tp(const char* tp_basename) +void enable_single_tp(int tp) { - bool found = false; - - for(int i = 0; i < TP_VAL_MAX && !found; i++) + if(tp == -1) { - if(strcmp(tp_names[i], tp_basename) == 0) - { - oargs.tp_of_interest.tp[i] = true; - found = true; - } + /* In this case we won't have any tracepoint enabled. */ + tp_is_set = true; + return; } - if(!found) + if(tp < 0 || tp >= TP_VAL_MAX) { - fprintf(stderr, "Tracepoint '%s' not found. Unsupported or wrong parameter?\n", tp_basename); - fprintf(stderr, "Please choose between:\n"); - for(int i = 0; i < TP_VAL_MAX; i++) - { - fprintf(stderr, "\t* %s\n", tp_names[i]); - } + fprintf(stderr, "Unexistent tp code: %d. Wrong parameter?\n", tp); + print_supported_tracepoints(); exit(EXIT_FAILURE); } - else - { - tp_is_set = true; - } + oargs.tp_of_interest.tp[tp] = true; + tp_is_set = true; } void enable_single_ppm_sc(int ppm_sc_code) @@ -102,13 +96,14 @@ void enable_single_ppm_sc(int ppm_sc_code) if(ppm_sc_code < 0 || ppm_sc_code >= PPM_SC_MAX) { fprintf(stderr, "Unexistent ppm_sc code: %d. Wrong parameter?\n", ppm_sc_code); + print_supported_syscalls(); exit(EXIT_FAILURE); } oargs.ppm_sc_of_interest.ppm_sc[ppm_sc_code] = true; ppm_sc_is_set = true; } -void set_enabled_syscalls() +void check_enabled_syscalls() { printf("---------------------- INTERESTING SYSCALLS ----------------------\n"); if(ppm_sc_is_set) @@ -133,7 +128,7 @@ void set_enabled_syscalls() printf("------------------------------------------------------------------\n\n"); } -void set_enabled_tracepoint() +void check_enabled_tracepoints() { printf("---------------------- ENABLED TRACEPOINTS ----------------------\n"); if(tp_is_set) @@ -433,6 +428,7 @@ void print_sorted_syscalls(char string_vector[SYSCALL_TABLE_SIZE][SYSCALL_NAME_M printf("Interesting syscalls: %d\n", dim); } +/// TODO: Probably we need to remove these 2 methods at the end. void print_UF_NEVER_DROP_syscalls() { char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; @@ -531,9 +527,17 @@ void print_supported_syscalls() } } -/*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ +void print_supported_tracepoints() +{ + printf("\n------- Print supported tracepoints: \n"); + + for(int j = 0; j < TP_VAL_MAX; j++) + { + printf("- %-25s tp_code: (%d)\n", tp_names[j], j); + } +} -/*=============================== PRINT SYSCALLS VALIDATION ===========================*/ +/// TODO: we need to move this validation outside this example void validate_syscalls() { @@ -580,7 +584,7 @@ void validate_syscalls() } } -/*=============================== PRINT SYSCALLS VALIDATION ===========================*/ +/*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ /*=============================== PRINT CAPTURE INFO ===========================*/ @@ -593,8 +597,8 @@ void print_help() printf("'%s': enable modern BPF probe.\n", MODERN_BPF_OPTION); printf("'%s ': read events from scap file.\n", SCAP_FILE_OPTION); printf("\n------> CONFIGURATIONS OPTIONS\n"); - printf("'%s ': enable only requested tracepoint (sys_enter, sys_exit, sched_process_exit, sched_switch, page_fault_user, page_fault_kernel, signal_deliver, sched_process_fork, sched_process_exec). Can be passed multiple times.\n", TP_OPTION); - printf("'%s ': enable only requested syscall. Can be passed multiple times.\n", PPM_SC_OPTION); + printf("'%s ': enable only requested tracepoint (sys_enter, sys_exit, sched_process_exit, sched_switch, page_fault_user, page_fault_kernel, signal_deliver, sched_process_fork, sched_process_exec). Can be passed multiple times.\n", TP_OPTION); + printf("'%s ': enable only requested syscall (this is our internal ppm syscall code not the system syscall code). Can be passed multiple times.\n", PPM_SC_OPTION); printf("'%s ': number of events to catch before terminating. (default: UINT64_MAX)\n", NUM_EVENTS_OPTION); printf("'%s ': every event of this type will be printed to console. (default: -1, no print)\n", EVENT_TYPE_OPTION); printf("\n------> VALIDATION OPTIONS\n"); @@ -608,20 +612,20 @@ void print_help() void print_scap_source() { printf("\n---------------------- SCAP SOURCE ----------------------\n"); - if(strncmp(oargs.engine_name, KMOD_ENGINE, KMOD_ENGINE_LEN) == 0) + if(strcmp(oargs.engine_name, KMOD_ENGINE) == 0) { printf("* Kernel module.\n"); } - else if(strncmp(oargs.engine_name, BPF_ENGINE, BPF_ENGINE_LEN) == 0) + else if(strcmp(oargs.engine_name, BPF_ENGINE) == 0) { struct scap_bpf_engine_params* params = oargs.engine_params; printf("* BPF probe: '%s'\n", params->bpf_probe); } - else if(strncmp(oargs.engine_name, MODERN_BPF_ENGINE, MODERN_BPF_ENGINE_LEN) == 0) + else if(strcmp(oargs.engine_name, MODERN_BPF_ENGINE) == 0) { printf("* Modern BPF probe.\n"); } - else if(strncmp(oargs.engine_name, SAVEFILE_ENGINE, SAVEFILE_ENGINE_LEN) == 0) + else if(strcmp(oargs.engine_name, SAVEFILE_ENGINE) == 0) { struct scap_savefile_engine_params* params = oargs.engine_params; printf("* Scap file: '%s'.\n", params->fname); @@ -637,28 +641,27 @@ void print_scap_source() void print_configurations() { - printf("---------------------- CONFIGURATIONS ----------------------\n"); + printf("--------------------- CONFIGURATIONS ----------------------\n"); printf("* Print single event type: %d (`-1` means no event to print).\n", evt_type); printf("* Run until '%lu' events are catched.\n", num_events); - printf("--------------------------------------------------------------\n\n"); + printf("-----------------------------------------------------------\n\n"); } void print_start_capture() { - - if(strncmp(oargs.engine_name, KMOD_ENGINE, KMOD_ENGINE_LEN) == 0) + if(strcmp(oargs.engine_name, KMOD_ENGINE) == 0) { printf("* OK! Kernel module correctly loaded.\n"); } - else if(strncmp(oargs.engine_name, BPF_ENGINE, BPF_ENGINE_LEN) == 0) + else if(strcmp(oargs.engine_name, BPF_ENGINE) == 0) { printf("* OK! BPF probe correctly loaded: NO VERIFIER ISSUES :)\n"); } - else if(strncmp(oargs.engine_name, MODERN_BPF_ENGINE, MODERN_BPF_ENGINE_LEN) == 0) + else if(strcmp(oargs.engine_name, MODERN_BPF_ENGINE) == 0) { printf("* OK! modern BPF probe correctly loaded: NO VERIFIER ISSUES :)\n"); } - else if(strncmp(oargs.engine_name, SAVEFILE_ENGINE, SAVEFILE_ENGINE_LEN) == 0) + else if(strcmp(oargs.engine_name, SAVEFILE_ENGINE) == 0) { printf("* OK! Ready to read from scap file.\n"); printf("\n* Reading from scap file...\n"); @@ -719,26 +722,27 @@ void parse_CLI_options(int argc, char** argv) /*=============================== SCAP SOURCES ===========================*/ /*=============================== CONFIGURATIONS ===========================*/ + if(!strcmp(argv[i], TP_OPTION)) { if(!(i + 1 < argc)) { - printf("\nYou need to specify also the basename of the tracepoint you are interested in! Bye!\n"); + print_supported_tracepoints(); + printf("\nYou need to specify also the number of the tracepoint you are interested in! Bye!\n"); exit(EXIT_FAILURE); } - enable_single_tp(argv[++i]); + enable_single_tp(atoi(argv[++i])); } - if(!strcmp(argv[i], PPM_SC_OPTION)) { if(!(i + 1 < argc)) { + print_supported_syscalls(); printf("\nYou need to specify also the syscall ppm_sc code! Bye!\n"); exit(EXIT_FAILURE); } enable_single_ppm_sc(atoi(argv[++i])); } - if(!strcmp(argv[i], NUM_EVENTS_OPTION)) { if(!(i + 1 < argc)) @@ -760,27 +764,22 @@ void parse_CLI_options(int argc, char** argv) /*=============================== CONFIGURATIONS ===========================*/ - /*=============================== VALIDATION ===========================*/ + /*=============================== PRINT ===========================*/ if(!strcmp(argv[i], VALIDATION_OPTION)) { validate_syscalls(); exit(EXIT_SUCCESS); } - - /*=============================== VALIDATION ===========================*/ - - /*=============================== PRINT ===========================*/ - if(!strcmp(argv[i], PRINT_SYSCALLS_OPTION)) { print_UF_NEVER_DROP_syscalls(); print_EF_MODIFIES_STATE_syscalls(); print_both_syscalls(); print_supported_syscalls(); + print_supported_tracepoints(); exit(EXIT_SUCCESS); } - if(!strcmp(argv[i], PRINT_HELP_OPTION)) { print_help(); @@ -790,7 +789,7 @@ void parse_CLI_options(int argc, char** argv) /*=============================== PRINT ===========================*/ } - if(strncmp(oargs.engine_name, UNKNOWN_ENGINE, UNKNOWN_ENGINE_LEN) == 0) + if(strcmp(oargs.engine_name, UNKNOWN_ENGINE) == 0) { printf("\nSource not specified! Bye!\n"); exit(EXIT_FAILURE); @@ -845,7 +844,7 @@ static void signal_callback(int signal) int main(int argc, char** argv) { - char error[SCAP_LASTERR_SIZE]; + char error[SCAP_LASTERR_SIZE] = {0}; int32_t res = 0; scap_evt* ev = NULL; uint16_t cpuid = 0; @@ -862,6 +861,10 @@ int main(int argc, char** argv) print_configurations(); + check_enabled_syscalls(); + + check_enabled_tracepoints(); + g_h = scap_open(&oargs, error, &res); if(g_h == NULL || res != SCAP_SUCCESS) { diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index e3dfafbfe7..3889c678df 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1215,12 +1215,12 @@ int scap_get_modifies_state_tracepoints(uint32_t* tp_array) tp_array[SYS_ENTER] = 1; tp_array[SYS_EXIT] = 1; - tp_array[SCHED_SWITCH] = 1; tp_array[SCHED_PROC_EXIT] = 1; + tp_array[SCHED_SWITCH] = 1; /* With `aarch64` and `s390x` we need also this, * in `x86` they are not considered at all. */ - tp_array[SCHED_PROC_EXEC] = 1; + tp_array[SCHED_PROC_FORK] = 1; tp_array[SCHED_PROC_EXEC] = 1; return SCAP_SUCCESS; } diff --git a/userspace/libsinsp/examples/test.cpp b/userspace/libsinsp/examples/test.cpp index 36faa25556..f981e71239 100644 --- a/userspace/libsinsp/examples/test.cpp +++ b/userspace/libsinsp/examples/test.cpp @@ -36,7 +36,7 @@ static bool g_interrupted = false; static const uint8_t g_backoff_timeout_secs = 2; static bool g_all_threads = false; static bool json_dump_init_success = false; -string engine_string = "kmod"; +string engine_string = KMOD_ENGINE; /* Default for backward compatibility. */ string filter_string = ""; string file_path = ""; string bpf_path = ""; @@ -64,6 +64,7 @@ static void usage() Overview: Goal of sinsp-example binary is to test and debug sinsp functionality and print events to STDOUT. All drivers are supported. Options: +<<<<<<< HEAD -h, --help Print this page. -f , --filter Filter string for events (see https://falco.org/docs/rules/supported-fields/ for supported fields). -j, --json Use JSON as the output format (STDOUT). @@ -73,6 +74,17 @@ Overview: Goal of sinsp-example binary is to test and debug sinsp functionality -d , --buffer-dim Buffer dimension. -s , --file-path Scap file path. -o , --output-fields-json [JSON support only, can also use without -j] Output fields string (see for supported display fields) that overwrites JSON default output fields for all events. * at the beginning prints JSON keys with null values, else no null fields are printed. +======= + -h, --help Print this page. + -f , --filter Filter string for events (see https://falco.org/docs/rules/supported-fields/ for supported fields). + -j, --json Use JSON as the output format. + -a, --all-threads Output information about all threads, not just the main one. + -b , --bpf BPF probe. + -m, --modern_bpf modern BPF probe. + -k, --kmod Kernel module + -s , --scap_file Scap file + -d , --buffer_dim Buffer dimension. +>>>>>>> 06e716b3 (fix(libscap/libsinsp): allow examples to work correctly) )"; cout << usage << endl; } @@ -86,10 +98,11 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) {"filter", required_argument, 0, 'f'}, {"json", no_argument, 0, 'j'}, {"all-threads", no_argument, 0, 'a'}, - {"engine", required_argument, 0, 'e'}, - {"bpf-path", required_argument, 0, 'b'}, - {"buffer-dim", required_argument, 0, 'd'}, - {"file-path", required_argument, 0, 's'}, + {"bpf", required_argument, 0, 'b'}, + {"modern_bpf", no_argument, 0, 'm'}, + {"kmod", no_argument, 0, 'k'}, + {"scap_file", required_argument, 0, 's'}, + {"buffer_dim", required_argument, 0, 'd'}, {"output-fields-json", required_argument, 0, 'o'}, {0, 0, 0, 0}}; @@ -113,18 +126,23 @@ void parse_CLI_options(sinsp& inspector, int argc, char** argv) case 'a': g_all_threads = true; break; - case 'e': - engine_string = optarg; - break; case 'b': + engine_string = BPF_ENGINE; bpf_path = optarg; break; - case 'd': - buffer_dim = strtoul(optarg, NULL, 10); + case 'm': + engine_string = MODERN_BPF_ENGINE; + break; + case 'k': + engine_string = KMOD_ENGINE; break; case 's': + engine_string = SAVEFILE_ENGINE; file_path = optarg; break; + case 'd': + buffer_dim = strtoul(optarg, NULL, 10); + break; case 'o': output_fields_json = optarg; json_dump_init(inspector); @@ -141,9 +159,13 @@ void open_engine(sinsp& inspector) { std::cout << "-- Try to open: '" + engine_string + "' engine." << std::endl; + /* Get only necessary tracepoints. */ + std::unordered_set tp_set = inspector.enforce_sinsp_state_tracepoints(); + std::unordered_set ppm_sc; + if(!engine_string.compare(KMOD_ENGINE)) { - inspector.open_kmod(buffer_dim); + inspector.open_kmod(buffer_dim, ppm_sc, tp_set); } else if(!engine_string.compare(BPF_ENGINE)) { @@ -156,15 +178,7 @@ void open_engine(sinsp& inspector) { std::cerr << bpf_path << std::endl; } - inspector.open_bpf(buffer_dim, bpf_path.c_str()); - } - else if(!engine_string.compare(UDIG_ENGINE)) - { - inspector.open_udig(); - } - else if(!engine_string.compare(NODRIVER_ENGINE)) - { - inspector.open_nodriver(); + inspector.open_bpf(buffer_dim, bpf_path.c_str(), ppm_sc, tp_set); } else if(!engine_string.compare(SAVEFILE_ENGINE)) { @@ -175,24 +189,9 @@ void open_engine(sinsp& inspector) } inspector.open_savefile(file_path.c_str(), 0); } - else if(!engine_string.compare(SOURCE_PLUGIN_ENGINE)) - { - std::cerr << "Not supported right now." << std::endl; - exit(EXIT_SUCCESS); - } - else if(!engine_string.compare(GVISOR_ENGINE)) - { - std::cerr << "Not supported right now." << std::endl; - exit(EXIT_SUCCESS); - } else if(!engine_string.compare(MODERN_BPF_ENGINE)) { - inspector.open_modern_bpf(buffer_dim); - } - else if(!engine_string.compare(TEST_INPUT_ENGINE)) - { - std::cerr << "Not supported right now." << std::endl; - exit(EXIT_SUCCESS); + inspector.open_modern_bpf(buffer_dim, ppm_sc, tp_set); } else { @@ -256,7 +255,6 @@ sinsp_evt* get_event(sinsp& inspector, std::function h int32_t res = inspector.next(&ev); - if(res == SCAP_SUCCESS) { return ev; diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index e6bac914d5..93d76c4609 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -472,8 +472,7 @@ void sinsp::mark_ppm_sc_of_interest(uint32_t ppm_sc, bool enable) std::unordered_set sinsp::enforce_sinsp_state_ppm_sc(std::unordered_set ppm_sc_of_interest) { - std::vector minimum_syscalls; - minimum_syscalls.reserve(PPM_SC_MAX); + std::vector minimum_syscalls(PPM_SC_MAX, 0); /* Should never happen but just to be sure. */ if(scap_get_modifies_state_ppm_sc(minimum_syscalls.data()) != SCAP_SUCCESS) @@ -493,9 +492,8 @@ std::unordered_set sinsp::enforce_sinsp_state_ppm_sc(std::unordered_se std::unordered_set sinsp::enforce_sinsp_state_tracepoints(std::unordered_set tp_of_interest) { - std::vector minimum_tracepoints; - minimum_tracepoints.reserve(TP_VAL_MAX); - + std::vector minimum_tracepoints(TP_VAL_MAX, 0); + /* Should never happen but just to be sure. */ if(scap_get_modifies_state_tracepoints(minimum_tracepoints.data()) != SCAP_SUCCESS) { From 4ce017f11088ef203752579676632c7b314d402f Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sun, 28 Aug 2022 21:00:29 +0000 Subject: [PATCH 25/29] update(modern_bpf_engine): support interesting syscalls/tracepoints Signed-off-by: Andrea Terzolo --- test/modern_bpf/event_class/event_class.cpp | 4 +- userspace/libpman/include/libpman.h | 18 ++--- userspace/libpman/src/maps.c | 23 +----- .../engine/modern_bpf/scap_modern_bpf.c | 78 +++++++++++++++++-- 4 files changed, 83 insertions(+), 40 deletions(-) diff --git a/test/modern_bpf/event_class/event_class.cpp b/test/modern_bpf/event_class/event_class.cpp index 3c98e3cb7c..2c430d1975 100644 --- a/test/modern_bpf/event_class/event_class.cpp +++ b/test/modern_bpf/event_class/event_class.cpp @@ -96,12 +96,12 @@ event_test::event_test(int syscall_id, int event_direction) void event_test::mark_single_64bit_syscall_as_interesting(int interesting_syscall_id) { - pman_mark_single_64bit_syscall_as_interesting(interesting_syscall_id); + pman_mark_single_64bit_syscall(interesting_syscall_id, true); } void event_test::mark_all_64bit_syscalls_as_uninteresting() { - pman_mark_all_64bit_syscalls_as_uninteresting(); + pman_clean_all_64bit_interesting_syscalls(); } void event_test::enable_capture() diff --git a/userspace/libpman/include/libpman.h b/userspace/libpman/include/libpman.h index efcb76e4aa..a38c62cc42 100644 --- a/userspace/libpman/include/libpman.h +++ b/userspace/libpman/include/libpman.h @@ -282,29 +282,23 @@ extern "C" int pman_finalize_maps_after_loading(void); /** - * @brief For every syscall set if it is interesting or not. + * @brief Mark a single syscall as (un)interesting * - * @param intersting_syscalls array of size `SYSCALL_TABLE_SIZE` that says - * if the single syscall is interesting or not. + * @param syscall_id syscall system id. + * @param interesting true if the syscall must be marked as interesting. + * */ - void pman_fill_64bit_interesting_syscalls_table(bool* intersting_syscalls); + void pman_mark_single_64bit_syscall(int syscall_id, bool interesting); ///////////////////////////// // TEST HELPERS ///////////////////////////// #ifdef TEST_HELPERS - /** - * @brief Mark a single syscall as interesting - * - * @param intersting_syscall_id syscall id. - */ - void pman_mark_single_64bit_syscall_as_interesting(int intersting_syscall_id); - /** * @brief Mark all syscalls as uninteresting. */ - void pman_mark_all_64bit_syscalls_as_uninteresting(void); + void pman_clean_all_64bit_interesting_syscalls(void); /** * @brief Print some statistics about events captured and diff --git a/userspace/libpman/src/maps.c b/userspace/libpman/src/maps.c index 8360e52bca..a880381f4e 100644 --- a/userspace/libpman/src/maps.c +++ b/userspace/libpman/src/maps.c @@ -67,12 +67,7 @@ void pman_set_snaplen(uint32_t desired_snaplen) } #ifdef TEST_HELPERS -void pman_mark_single_64bit_syscall_as_interesting(int intersting_syscall_id) -{ - g_state.skel->bss->g_64bit_interesting_syscalls_table[intersting_syscall_id] = true; -} - -void pman_mark_all_64bit_syscalls_as_uninteresting() +void pman_clean_all_64bit_interesting_syscalls() { /* All syscalls are not interesting. */ for(int j = 0; j < SYSCALL_TABLE_SIZE; ++j) @@ -82,20 +77,9 @@ void pman_mark_all_64bit_syscalls_as_uninteresting() } #endif -static void set_all_64bit_syscalls_interesting() -{ - for(int j = 0; j < SYSCALL_TABLE_SIZE; ++j) - { - g_state.skel->bss->g_64bit_interesting_syscalls_table[j] = true; - } -} - -void pman_fill_64bit_interesting_syscalls_table(bool* intersting_syscalls) +void pman_mark_single_64bit_syscall(int intersting_syscall_id, bool interesting) { - for(int j = 0; j < SYSCALL_TABLE_SIZE; ++j) - { - g_state.skel->bss->g_64bit_interesting_syscalls_table[j] = intersting_syscalls[j]; - } + g_state.skel->bss->g_64bit_interesting_syscalls_table[intersting_syscall_id] = interesting; } /*=============================== BPF GLOBAL VARIABLES ===============================*/ @@ -275,7 +259,6 @@ int pman_finalize_maps_after_loading() int err; /* set bpf global variables. */ - set_all_64bit_syscalls_interesting(); pman_set_snaplen(80); /* We have to fill all ours tail tables. */ diff --git a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c index 8eb02a329c..dc0cf3295d 100644 --- a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c +++ b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c @@ -26,6 +26,71 @@ limitations under the License. #include "noop.h" #include "../common/strlcpy.h" +/*=============================== UTILS ===============================*/ + +static int32_t attach_interesting_tracepoints(bool* tp_array) +{ + int ret = SCAP_SUCCESS; + if(tp_array == NULL) + { + return SCAP_FAILURE; + } + + for(int tp = 0; tp < TP_VAL_MAX && ret == SCAP_SUCCESS; tp++) + { + /* If the tracepoint is not interesting, continue */ + if(!tp_array[tp]) + { + continue; + } + + switch(tp) + { + case SYS_ENTER: + ret = pman_attach_syscall_enter_dispatcher(); + break; + + case SYS_EXIT: + ret = pman_attach_syscall_exit_dispatcher(); + break; + + default: + /* Do nothing right now. */ + break; + } + } + return ret; +} + +static void update_single_64bit_syscall_of_interest(int ppm_sc, bool interesting) +{ + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + if(g_syscall_code_routing_table[syscall_nr] == ppm_sc) + { + pman_mark_single_64bit_syscall(syscall_nr, interesting); + } + } +} + +/// TODO: from `oargs` we should directly receive a table of internal syscall code, not ppm_sc. +static int32_t populate_64bit_interesting_syscalls_table(bool* ppm_sc_array) +{ + int ret = SCAP_SUCCESS; + if(ppm_sc_array == NULL) + { + return SCAP_FAILURE; + } + + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + update_single_64bit_syscall_of_interest(ppm_sc, ppm_sc_array[ppm_sc]); + } + return ret; +} + +/*=============================== UTILS ===============================*/ + /* Right now this is not used */ bool scap_modern_bpf__match(scap_open_args* oargs) { @@ -70,7 +135,11 @@ static int32_t scap_modern_bpf__configure(struct scap_engine_handle engine, enum case SCAP_SNAPLEN: pman_set_snaplen(arg1); case SCAP_EVENTMASK: - /* Not supported */ + /* We use this setting just to modify the interesting syscalls. */ + if(arg1 == SCAP_EVENTMASK_SET || arg1 == SCAP_EVENTMASK_UNSET) + { + update_single_64bit_syscall_of_interest(arg2, arg1 == SCAP_EVENTMASK_SET); + } return SCAP_SUCCESS; case SCAP_DYNAMIC_SNAPLEN: /* Not supported */ @@ -129,8 +198,8 @@ int32_t scap_modern_bpf__init(scap_t* handle, scap_open_args* oargs) ret = ret ?: pman_load_probe(); ret = ret ?: pman_finalize_maps_after_loading(); ret = ret ?: pman_finalize_ringbuf_array_after_loading(); - ret = ret ?: pman_attach_syscall_enter_dispatcher(); - ret = ret ?: pman_attach_syscall_exit_dispatcher(); + ret = ret ?: populate_64bit_interesting_syscalls_table(oargs->ppm_sc_of_interest.ppm_sc); + ret = ret ?: attach_interesting_tracepoints(oargs->tp_of_interest.tp); if(ret != SCAP_SUCCESS) { return ret; @@ -139,9 +208,6 @@ int32_t scap_modern_bpf__init(scap_t* handle, scap_open_args* oargs) handle->m_api_version = pman_get_probe_api_ver(); handle->m_schema_version = pman_get_probe_schema_ver(); - /// TODO: Here we miss the simple consumer logic. Right now - /// all syscalls and tracepoints are interesting. - return SCAP_SUCCESS; } From dfecb831a3fedd3c8056f91e484c7a7e886e4f9a Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Sun, 28 Aug 2022 21:05:19 +0000 Subject: [PATCH 26/29] cleanup(bpf_engine): remove useless checks Signed-off-by: Andrea Terzolo --- userspace/libscap/engine/bpf/scap_bpf.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 44c4f722f5..7989f85d30 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -944,19 +944,9 @@ static int32_t set_single_syscall_of_interest(struct bpf_engine *handle, int ppm static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle, scap_open_args *oargs) { - bool enable; for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - if(oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) - { - enable = true; - } - else - { - enable = false; - } - - if(set_single_syscall_of_interest(handle, ppm_sc, enable) != SCAP_SUCCESS) + if(set_single_syscall_of_interest(handle, ppm_sc, oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) != SCAP_SUCCESS) { return SCAP_FAILURE; } @@ -967,16 +957,7 @@ static int32_t populate_interesting_syscalls_map(struct bpf_engine *handle, scap static int32_t update_interesting_syscalls_map(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) { struct bpf_engine *handle = engine.m_handle; - bool enable; - if(op == SCAP_EVENTMASK_SET) - { - enable = true; - } - else - { - enable = false; - } - return set_single_syscall_of_interest(handle, ppm_sc, enable); + return set_single_syscall_of_interest(handle, ppm_sc, op == SCAP_EVENTMASK_SET); } static int32_t populate_event_table_map(struct bpf_engine *handle) From 6645f62812af6c9e1d217b089ea4ce6801dce5c7 Mon Sep 17 00:00:00 2001 From: Andrea Terzolo Date: Mon, 29 Aug 2022 09:09:57 +0000 Subject: [PATCH 27/29] update(engines): support `SCAP_EVENTMASK_ZERO` in all the engines Signed-off-by: Andrea Terzolo Co-authored-by: Federico Di Pierro --- userspace/libpman/include/libpman.h | 12 +- userspace/libpman/src/maps.c | 2 - userspace/libscap/engine/bpf/scap_bpf.c | 26 +- userspace/libscap/engine/kmod/scap_kmod.c | 96 ++--- .../engine/modern_bpf/scap_modern_bpf.c | 4 + .../libscap/examples/01-open/scap_open.c | 377 +++++++++--------- userspace/libscap/scap.c | 14 + userspace/libsinsp/sinsp.h | 4 +- 8 files changed, 289 insertions(+), 246 deletions(-) diff --git a/userspace/libpman/include/libpman.h b/userspace/libpman/include/libpman.h index a38c62cc42..3bbb64657b 100644 --- a/userspace/libpman/include/libpman.h +++ b/userspace/libpman/include/libpman.h @@ -286,20 +286,20 @@ extern "C" * * @param syscall_id syscall system id. * @param interesting true if the syscall must be marked as interesting. - * + * */ void pman_mark_single_64bit_syscall(int syscall_id, bool interesting); - ///////////////////////////// - // TEST HELPERS - ///////////////////////////// -#ifdef TEST_HELPERS - /** * @brief Mark all syscalls as uninteresting. */ void pman_clean_all_64bit_interesting_syscalls(void); + ///////////////////////////// + // TEST HELPERS + ///////////////////////////// +#ifdef TEST_HELPERS + /** * @brief Print some statistics about events captured and * events dropped diff --git a/userspace/libpman/src/maps.c b/userspace/libpman/src/maps.c index a880381f4e..21a3679e3e 100644 --- a/userspace/libpman/src/maps.c +++ b/userspace/libpman/src/maps.c @@ -66,7 +66,6 @@ void pman_set_snaplen(uint32_t desired_snaplen) g_state.skel->bss->g_settings.snaplen = desired_snaplen; } -#ifdef TEST_HELPERS void pman_clean_all_64bit_interesting_syscalls() { /* All syscalls are not interesting. */ @@ -75,7 +74,6 @@ void pman_clean_all_64bit_interesting_syscalls() g_state.skel->bss->g_64bit_interesting_syscalls_table[j] = false; } } -#endif void pman_mark_single_64bit_syscall(int intersting_syscall_id, bool interesting) { diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 7989f85d30..986b6f962f 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -1670,6 +1670,30 @@ static int32_t unsupported_config(struct scap_engine_handle engine, const char* return SCAP_FAILURE; } +static int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) +{ + int32_t ret = SCAP_SUCCESS; + switch(op) + { + case SCAP_EVENTMASK_ZERO: + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX && ret==SCAP_SUCCESS; ppm_sc++) + { + ret = update_interesting_syscalls_map(engine, SCAP_EVENTMASK_UNSET, ppm_sc); + } + break; + + case SCAP_EVENTMASK_SET: + case SCAP_EVENTMASK_UNSET: + ret = update_interesting_syscalls_map(engine, op, ppm_sc); + break; + + default: + ret = SCAP_FAILURE; + break; + } + return ret; +} + static int32_t configure(struct scap_engine_handle engine, enum scap_setting setting, unsigned long arg1, unsigned long arg2) { switch(setting) @@ -1692,7 +1716,7 @@ static int32_t configure(struct scap_engine_handle engine, enum scap_setting set case SCAP_SNAPLEN: return scap_bpf_set_snaplen(engine, arg1); case SCAP_EVENTMASK: - return update_interesting_syscalls_map(engine, arg1, arg2); + return scap_bpf_handle_event_mask(engine, arg1, arg2); case SCAP_DYNAMIC_SNAPLEN: if(arg1 == 0) { diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index a0135d2e6c..f5402d6866 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -74,6 +74,54 @@ static uint32_t get_max_consumers() return 0; } +/// TODO: we need to pass directly the system syscall number not the `ppm_sc` here. +int32_t scap_kmod_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) +{ + struct scap_device_set *devset = &engine.m_handle->m_dev_set; + if (op != SCAP_EVENTMASK_ZERO) + { + int ioctl_op = op == SCAP_EVENTMASK_SET ? PPM_IOCTL_MASK_SET_EVENT : PPM_IOCTL_MASK_UNSET_EVENT; + // Find any syscall table entry that matches requested ppm_sc code + // then for any syscall, (un)set its enter and exit events + for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) + { + if (g_syscall_code_routing_table[i] == ppm_sc) + { + enum ppm_event_type enter_ev = g_syscall_table[i].enter_event_type; + enum ppm_event_type exit_ev = g_syscall_table[i].exit_event_type; + if(ioctl(devset->m_devs[0].m_fd, ioctl_op, enter_ev)) + { + snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, + "%s(%d) failed for event type %d", + __FUNCTION__, op, enter_ev); + ASSERT(false); + return SCAP_FAILURE; + } + if(ioctl(devset->m_devs[0].m_fd, ioctl_op, exit_ev)) + { + snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, + "%s(%d) failed for event type %d", + __FUNCTION__, op, exit_ev); + ASSERT(false); + return SCAP_FAILURE; + } + } + } + } + else + { + if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_MASK_ZERO_EVENTS, 0)) + { + snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, + "%s(%d) failed", + __FUNCTION__, op); + ASSERT(false); + return SCAP_FAILURE; + } + } + return SCAP_SUCCESS; +} + int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) { uint32_t j = 0; @@ -470,54 +518,6 @@ int32_t scap_kmod_set_snaplen(struct scap_engine_handle engine, uint32_t snaplen return SCAP_SUCCESS; } -/// TODO: we need to pass directly the system syscall number not the `ppm_sc` here. -int32_t scap_kmod_handle_event_mask(struct scap_engine_handle engine, uint32_t op, uint32_t ppm_sc) -{ - struct scap_device_set *devset = &engine.m_handle->m_dev_set; - if (op != SCAP_EVENTMASK_ZERO) - { - int ioctl_op = op == SCAP_EVENTMASK_SET ? PPM_IOCTL_MASK_SET_EVENT : PPM_IOCTL_MASK_UNSET_EVENT; - // Find any syscall table entry that matches requested ppm_sc code - // then for any syscall, (un)set its enter and exit events - for (int i = 0; i < SYSCALL_TABLE_SIZE; i++) - { - if (g_syscall_code_routing_table[i] == ppm_sc) - { - enum ppm_event_type enter_ev = g_syscall_table[i].enter_event_type; - enum ppm_event_type exit_ev = g_syscall_table[i].exit_event_type; - if(ioctl(devset->m_devs[0].m_fd, ioctl_op, enter_ev)) - { - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, - "%s(%d) failed for event type %d", - __FUNCTION__, op, enter_ev); - ASSERT(false); - return SCAP_FAILURE; - } - if(ioctl(devset->m_devs[0].m_fd, ioctl_op, exit_ev)) - { - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, - "%s(%d) failed for event type %d", - __FUNCTION__, op, exit_ev); - ASSERT(false); - return SCAP_FAILURE; - } - } - } - } - else - { - if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_MASK_ZERO_EVENTS, 0)) - { - snprintf(engine.m_handle->m_lasterr, SCAP_LASTERR_SIZE, - "%s(%d) failed", - __FUNCTION__, op); - ASSERT(false); - return SCAP_FAILURE; - } - } - return SCAP_SUCCESS; -} - int32_t scap_kmod_enable_dynamic_snaplen(struct scap_engine_handle engine) { // diff --git a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c index dc0cf3295d..c30f33c3f2 100644 --- a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c +++ b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c @@ -140,6 +140,10 @@ static int32_t scap_modern_bpf__configure(struct scap_engine_handle engine, enum { update_single_64bit_syscall_of_interest(arg2, arg1 == SCAP_EVENTMASK_SET); } + else if(arg1 == SCAP_EVENTMASK_ZERO) + { + pman_clean_all_64bit_interesting_syscalls(); + } return SCAP_SUCCESS; case SCAP_DYNAMIC_SNAPLEN: /* Not supported */ diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index dc4153d036..92b362fff0 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -65,6 +65,194 @@ uint16_t* lens16 = NULL; /* pointer used to print the length of event p char* valptr = NULL; /* pointer used to print the value of event params. */ /* pointer used to print the value of event params. */ struct timeval tval_start, tval_end, tval_result; +/*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ + +void print_sorted_syscalls(char string_vector[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN], int dim) +{ + char temp[SYSCALL_NAME_MAX_LEN]; + + /* storing strings in the lexicographical order */ + for(int i = 0; i < dim; ++i) + { + for(int j = i + 1; j < dim; ++j) + { + /* swapping strings if they are not in the lexicographical order */ + if(strcmp(string_vector[i], string_vector[j]) > 0) + { + strcpy(temp, string_vector[i]); + strcpy(string_vector[i], string_vector[j]); + strcpy(string_vector[j], temp); + } + } + } + + printf("\nSyscalls in the lexicographical order: \n"); + for(int i = 0; i < dim; i++) + { + printf("[%d] %s\n", i, string_vector[i]); + } + printf("Interesting syscalls: %d\n", dim); +} + +void print_UF_NEVER_DROP_syscalls() +{ + char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; + int interesting_syscall = 0; + + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + { + continue; + } + + if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) + { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); + } + } + } + + printf("\n------- Print UF_NEVER_DROP syscalls: \n"); + print_sorted_syscalls(str, interesting_syscall); +} + +void print_EF_MODIFIES_STATE_syscalls() +{ + char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; + int interesting_syscall = 0; + + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + { + continue; + } + + int enter_event = g_syscall_table[syscall_nr].enter_event_type; + if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) + { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); + } + } + } + + printf("\n------- Print EF_MODIFIES_STATE syscalls: \n"); + print_sorted_syscalls(str, interesting_syscall); +} + +void print_both_syscalls() +{ + char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; + int interesting_syscall = 0; + + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) + { + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) + { + continue; + } + + if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) + { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); + continue; + } + + int enter_event = g_syscall_table[syscall_nr].enter_event_type; + if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) + { + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); + } + } + } + + printf("\n------- Print 'EF_MODIFIES_STATE' and 'UF_NEVER_DROP' syscalls: \n"); + print_sorted_syscalls(str, interesting_syscall); +} + +void print_supported_syscalls() +{ + printf("\n------- Print supported syscalls: \n"); + + for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) + { + if(g_syscall_code_routing_table[syscall_nr] == PPM_SC_UNKNOWN) + { + continue; + } + int ppm_code = g_syscall_code_routing_table[syscall_nr]; + printf("- %-25s system_code: (%d) ppm_code: (%d)\n", g_syscall_info_table[ppm_code].name, syscall_nr, ppm_code); + } +} + +void print_supported_tracepoints() +{ + printf("\n------- Print supported tracepoints: \n"); + + for(int j = 0; j < TP_VAL_MAX; j++) + { + printf("- %-25s tp_code: (%d)\n", tp_names[j], j); + } +} + +/// TODO: we need to move this validation outside this example + +void validate_syscalls() +{ + enum ppm_syscall_code ppm_syscall_code = 0; + bool success = true; + /* For every syscall of the system. */ + for(int syscall_id = 0; syscall_id < SYSCALL_TABLE_SIZE; syscall_id++) + { + + ppm_syscall_code = g_syscall_code_routing_table[syscall_id]; + /* If the syscall has `UF_NEVER_DROP` flag we must have its name inside the + * `g_syscall_info_table`. + */ + if(g_syscall_table[syscall_id].flags & UF_NEVER_DROP && !g_syscall_info_table[ppm_syscall_code].name) + { + printf("ERROR: the syscall with real id `%d` has a `UF_NEVER_DROP` syscall in `g_syscall_table` but not a name in the `g_syscall_info_table`.\n", syscall_id); + success = false; + continue; + } + + if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E) + { + continue; + } + + /* This is an error since it means that a syscall we want to trace is not tracked in our `g_syscall_info_table`. + * We have `EC_UNKNOWN` when we don't have an entry in the `g_syscall_info_table`. + */ + if(g_syscall_info_table[ppm_syscall_code].category == EC_UNKNOWN) + { + printf("ERROR: the syscall with ppm code '%d' has an event associated but it is unknown in our `g_syscall_info_table`.\n", ppm_syscall_code); + success = false; + continue; + } + } + + if(success) + { + printf("\n[SUCCESS] Our table are consistent!\n"); + } + else + { + printf("\n[FAIL] Our table are not consistent!\n"); + } +} + +/*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ + +/*=============================== SYSCALLS/TRACEPOINTS ===========================*/ + void enable_single_tp(int tp) { if(tp == -1) @@ -153,6 +341,8 @@ void check_enabled_tracepoints() printf("-----------------------------------------------------------------\n\n"); } +/*=============================== SYSCALLS/TRACEPOINTS ===========================*/ + /*=============================== PRINT EVENT PARAMS ===========================*/ void print_ipv4(int starting_index) @@ -399,193 +589,6 @@ void print_event(scap_evt* ev) /*=============================== PRINT EVENT PARAMS ===========================*/ -/*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ - -void print_sorted_syscalls(char string_vector[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN], int dim) -{ - char temp[SYSCALL_NAME_MAX_LEN]; - - /* storing strings in the lexicographical order */ - for(int i = 0; i < dim; ++i) - { - for(int j = i + 1; j < dim; ++j) - { - /* swapping strings if they are not in the lexicographical order */ - if(strcmp(string_vector[i], string_vector[j]) > 0) - { - strcpy(temp, string_vector[i]); - strcpy(string_vector[i], string_vector[j]); - strcpy(string_vector[j], temp); - } - } - } - - printf("\nSyscalls in the lexicographical order: \n"); - for(int i = 0; i < dim; i++) - { - printf("[%d] %s\n", i, string_vector[i]); - } - printf("Interesting syscalls: %d\n", dim); -} - -/// TODO: Probably we need to remove these 2 methods at the end. -void print_UF_NEVER_DROP_syscalls() -{ - char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; - int interesting_syscall = 0; - - for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) - { - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) - { - if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) - { - continue; - } - - if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) - { - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); - } - } - } - - printf("\n------- Print UF_NEVER_DROP syscalls: \n"); - print_sorted_syscalls(str, interesting_syscall); -} - -void print_EF_MODIFIES_STATE_syscalls() -{ - char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; - int interesting_syscall = 0; - - for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) - { - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) - { - if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) - { - continue; - } - - int enter_event = g_syscall_table[syscall_nr].enter_event_type; - if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) - { - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); - } - } - } - - printf("\n------- Print EF_MODIFIES_STATE syscalls: \n"); - print_sorted_syscalls(str, interesting_syscall); -} - -void print_both_syscalls() -{ - char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; - int interesting_syscall = 0; - - for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) - { - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) - { - if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) - { - continue; - } - - if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) - { - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); - continue; - } - - int enter_event = g_syscall_table[syscall_nr].enter_event_type; - if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) - { - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); - } - } - } - - printf("\n------- Print 'EF_MODIFIES_STATE' and 'UF_NEVER_DROP' syscalls: \n"); - print_sorted_syscalls(str, interesting_syscall); -} - -void print_supported_syscalls() -{ - printf("\n------- Print supported syscalls: \n"); - - for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) - { - if(g_syscall_code_routing_table[syscall_nr] == PPM_SC_UNKNOWN) - { - continue; - } - int ppm_code = g_syscall_code_routing_table[syscall_nr]; - printf("- %-25s system_code: (%d) ppm_code: (%d)\n", g_syscall_info_table[ppm_code].name, syscall_nr, ppm_code); - } -} - -void print_supported_tracepoints() -{ - printf("\n------- Print supported tracepoints: \n"); - - for(int j = 0; j < TP_VAL_MAX; j++) - { - printf("- %-25s tp_code: (%d)\n", tp_names[j], j); - } -} - -/// TODO: we need to move this validation outside this example - -void validate_syscalls() -{ - enum ppm_syscall_code ppm_syscall_code = 0; - bool success = true; - /* For every syscall of the system. */ - for(int syscall_id = 0; syscall_id < SYSCALL_TABLE_SIZE; syscall_id++) - { - - ppm_syscall_code = g_syscall_code_routing_table[syscall_id]; - /* If the syscall has `UF_NEVER_DROP` flag we must have its name inside the - * `g_syscall_info_table`. - */ - if(g_syscall_table[syscall_id].flags & UF_NEVER_DROP && !g_syscall_info_table[ppm_syscall_code].name) - { - printf("ERROR: the syscall with real id `%d` has a `UF_NEVER_DROP` syscall in `g_syscall_table` but not a name in the `g_syscall_info_table`.\n", syscall_id); - success = false; - continue; - } - - if(g_syscall_table[syscall_id].enter_event_type == PPME_GENERIC_E) - { - continue; - } - - /* This is an error since it means that a syscall we want to trace is not tracked in our `g_syscall_info_table`. - * We have `EC_UNKNOWN` when we don't have an entry in the `g_syscall_info_table`. - */ - if(g_syscall_info_table[ppm_syscall_code].category == EC_UNKNOWN) - { - printf("ERROR: the syscall with ppm code '%d' has an event associated but it is unknown in our `g_syscall_info_table`.\n", ppm_syscall_code); - success = false; - continue; - } - } - - if(success) - { - printf("\n[SUCCESS] Our table are consistent!\n"); - } - else - { - printf("\n[FAIL] Our table are not consistent!\n"); - } -} - -/*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ - /*=============================== PRINT CAPTURE INFO ===========================*/ void print_help() diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 3889c678df..409f6ce173 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1378,6 +1378,20 @@ int64_t scap_get_readfile_offset(scap_t* handle) static int32_t scap_handle_eventmask(scap_t* handle, uint32_t op, uint32_t ppm_sc) { + switch(op) + { + case SCAP_EVENTMASK_SET: + case SCAP_EVENTMASK_UNSET: + case SCAP_EVENTMASK_ZERO: + break; + + default: + snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "%s(%d) internal error", __FUNCTION__, op); + ASSERT(false); + return SCAP_FAILURE; + break; + } + if(handle->m_vtable) { return handle->m_vtable->configure(handle->m_engine, SCAP_EVENTMASK, op, ppm_sc); diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index d31d73badd..0f2cffc6eb 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -835,7 +835,8 @@ class SINSP_PUBLIC sinsp : public capture_stats_source, public wmi_handle_source /*! \brief Mark desired syscall as (un)interesting, enabling or disabling its collection. This method receives a `ppm_sc` code, not a syscall system code, the same ppm_code - can match more than one system syscall. + can match more than one system syscall. You can find the available + `enum ppm_syscall_code` in `driver/ppm_events_public.h`. Please note that this method must be called when the inspector is already open to modify at runtime the interesting syscall set. @@ -951,7 +952,6 @@ VISIBILITY_PROTECTED m_mode = value; } -/// TODO: do we need this MACRO? VISIBILITY_PRIVATE // Doxygen doesn't understand VISIBILITY_PRIVATE From e2710fe0bc0218b20588965cd936a5e445f2d9f8 Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Wed, 31 Aug 2022 13:57:54 +0200 Subject: [PATCH 28/29] chore: fix multiple small nits. Co-authored-by: Mauro Ezequiel Moltrasio Signed-off-by: Federico Di Pierro --- driver/bpf/plumbing_helpers.h | 6 ++- driver/main.c | 3 +- driver/ppm_tp.h | 2 +- driver/tp_table.c | 16 +++--- userspace/libscap/engine/bpf/scap_bpf.c | 15 +++--- userspace/libscap/engine/kmod/scap_kmod.c | 10 +--- .../libscap/examples/01-open/scap_open.c | 53 ++++++++++--------- userspace/libsinsp/examples/test.cpp | 13 +---- userspace/libsinsp/sinsp.cpp | 2 +- 9 files changed, 53 insertions(+), 67 deletions(-) diff --git a/driver/bpf/plumbing_helpers.h b/driver/bpf/plumbing_helpers.h index cf27afc03b..336267ed8f 100644 --- a/driver/bpf/plumbing_helpers.h +++ b/driver/bpf/plumbing_helpers.h @@ -289,10 +289,12 @@ static __always_inline bool is_syscall_interesting(int id) bool *enabled = bpf_map_lookup_elem(&interesting_syscalls_table, &id); if (!enabled) - + { bpf_printk("no syscall_info for %d\n", id); + return false; + } - return enabled && *enabled; + return *enabled; } static __always_inline const struct ppm_event_info *get_event_info(enum ppm_event_type event_type) diff --git a/driver/main.c b/driver/main.c index 72f8b92fc2..979797de26 100644 --- a/driver/main.c +++ b/driver/main.c @@ -648,10 +648,9 @@ static int force_tp_set(u32 new_tp_set, u32 max_val) for(idx = 0; idx < max_val && ret == 0; idx++) { - ret = 0; new_val = new_tp_set & (1 << idx); curr_val = g_tracepoints_attached & (1 << idx); - if((new_val ^ curr_val) == 0) + if(new_val == curr_val) { // no change needed continue; diff --git a/driver/ppm_tp.h b/driver/ppm_tp.h index 0a1ae2608d..6b10bffe9a 100644 --- a/driver/ppm_tp.h +++ b/driver/ppm_tp.h @@ -1,6 +1,6 @@ #pragma once -/* | name | name | */ +/* | name | path | */ #define TP_FIELDS \ X(SYS_ENTER, "sys_enter") \ X(SYS_EXIT, "sys_exit") \ diff --git a/driver/tp_table.c b/driver/tp_table.c index c7e6edec9e..cf8e802f60 100644 --- a/driver/tp_table.c +++ b/driver/tp_table.c @@ -12,15 +12,17 @@ tp_values tp_from_name(const char *tp_path) { // Find last '/' occurrence to take only the basename const char *tp_name = strrchr(tp_path, '/'); - if (tp_name && strlen(tp_name) > 1) + if (tp_name == NULL || strlen(tp_name) <= 1) { - tp_name++; - for (int i = 0; i < TP_VAL_MAX; i++) + return -1; + } + + tp_name++; + for (int i = 0; i < TP_VAL_MAX; i++) + { + if (strcmp(tp_name, tp_names[i]) == 0) { - if (strcmp(tp_name, tp_names[i]) == 0) - { - return i; - } + return i; } } return -1; diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index 986b6f962f..8b776bc9cf 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -646,17 +646,14 @@ static int32_t load_tracepoint(struct bpf_engine* handle, const char *event, str static bool is_tp_enabled(interesting_tp_set *tp_of_interest, const char *shname) { - if (tp_of_interest) + tp_values val = tp_from_name(shname); + if(!tp_of_interest || val == -1) { - tp_values val = tp_from_name(shname); - if(val == -1) - { - // Not found? Enable it! - return true; - } - return tp_of_interest->tp[val]; + // Null tp set? Enable everything! + // Not found? Enable it! + return true; } - return true; + return tp_of_interest->tp[val]; } static int32_t load_bpf_file( diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index f5402d6866..8194d864ca 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -300,14 +300,8 @@ int32_t scap_kmod_init(scap_t *handle, scap_open_args *oargs) /* Set interesting Syscalls */ for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { - if(oargs->ppm_sc_of_interest.ppm_sc[ppm_sc]) - { - scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_SET, ppm_sc); - } - else - { - scap_kmod_handle_event_mask(engine, SCAP_EVENTMASK_UNSET, ppm_sc); - } + uint32_t op = oargs->ppm_sc_of_interest.ppm_sc[ppm_sc] ? SCAP_EVENTMASK_SET : SCAP_EVENTMASK_UNSET; + scap_kmod_handle_event_mask(engine, op, ppm_sc); } /* Set interesting Tracepoints */ diff --git a/userspace/libscap/examples/01-open/scap_open.c b/userspace/libscap/examples/01-open/scap_open.c index 92b362fff0..58a149b402 100644 --- a/userspace/libscap/examples/01-open/scap_open.c +++ b/userspace/libscap/examples/01-open/scap_open.c @@ -145,35 +145,31 @@ void print_EF_MODIFIES_STATE_syscalls() print_sorted_syscalls(str, interesting_syscall); } -void print_both_syscalls() +void print_sinsp_modifies_state_syscalls() { + uint32_t ppm_scs[PPM_SC_MAX]; char str[SYSCALL_TABLE_SIZE][SYSCALL_NAME_MAX_LEN]; int interesting_syscall = 0; + scap_get_modifies_state_ppm_sc(ppm_scs); + for(int ppm_sc = 0; ppm_sc < PPM_SC_MAX; ppm_sc++) { + if (!ppm_scs[ppm_sc]) + { + continue; + } for(int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { if(g_syscall_code_routing_table[syscall_nr] != ppm_sc) { continue; } - - if(g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) - { - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); - continue; - } - - int enter_event = g_syscall_table[syscall_nr].enter_event_type; - if(g_event_info[enter_event].flags & EF_MODIFIES_STATE) - { - strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); - } + strcpy(str[interesting_syscall++], g_syscall_info_table[ppm_sc].name); } } - printf("\n------- Print 'EF_MODIFIES_STATE' and 'UF_NEVER_DROP' syscalls: \n"); + printf("\n------- Print 'scap_get_modifies_state_ppm_sc' syscalls: \n"); print_sorted_syscalls(str, interesting_syscall); } @@ -204,7 +200,7 @@ void print_supported_tracepoints() /// TODO: we need to move this validation outside this example -void validate_syscalls() +bool validate_syscalls() { enum ppm_syscall_code ppm_syscall_code = 0; bool success = true; @@ -216,7 +212,7 @@ void validate_syscalls() /* If the syscall has `UF_NEVER_DROP` flag we must have its name inside the * `g_syscall_info_table`. */ - if(g_syscall_table[syscall_id].flags & UF_NEVER_DROP && !g_syscall_info_table[ppm_syscall_code].name) + if((g_syscall_table[syscall_id].flags & UF_NEVER_DROP) && !g_syscall_info_table[ppm_syscall_code].name) { printf("ERROR: the syscall with real id `%d` has a `UF_NEVER_DROP` syscall in `g_syscall_table` but not a name in the `g_syscall_info_table`.\n", syscall_id); success = false; @@ -241,12 +237,13 @@ void validate_syscalls() if(success) { - printf("\n[SUCCESS] Our table are consistent!\n"); + printf("\n[SUCCESS] Our tables are consistent!\n"); } else { - printf("\n[FAIL] Our table are not consistent!\n"); + printf("\n[FAIL] Our tables are not consistent!\n"); } + return success; } /*=============================== PRINT SUPPORTED SYSCALLS ===========================*/ @@ -291,7 +288,7 @@ void enable_single_ppm_sc(int ppm_sc_code) ppm_sc_is_set = true; } -void check_enabled_syscalls() +void enable_syscalls_and_print() { printf("---------------------- INTERESTING SYSCALLS ----------------------\n"); if(ppm_sc_is_set) @@ -316,7 +313,7 @@ void check_enabled_syscalls() printf("------------------------------------------------------------------\n\n"); } -void check_enabled_tracepoints() +void enable_tracepoints_and_print() { printf("---------------------- ENABLED TRACEPOINTS ----------------------\n"); if(tp_is_set) @@ -771,14 +768,20 @@ void parse_CLI_options(int argc, char** argv) if(!strcmp(argv[i], VALIDATION_OPTION)) { - validate_syscalls(); - exit(EXIT_SUCCESS); + if (validate_syscalls()) + { + exit(EXIT_SUCCESS); + } + else + { + exit(EXIT_FAILURE); + } } if(!strcmp(argv[i], PRINT_SYSCALLS_OPTION)) { print_UF_NEVER_DROP_syscalls(); print_EF_MODIFIES_STATE_syscalls(); - print_both_syscalls(); + print_sinsp_modifies_state_syscalls(); print_supported_syscalls(); print_supported_tracepoints(); exit(EXIT_SUCCESS); @@ -864,9 +867,9 @@ int main(int argc, char** argv) print_configurations(); - check_enabled_syscalls(); + enable_syscalls_and_print(); - check_enabled_tracepoints(); + enable_tracepoints_and_print(); g_h = scap_open(&oargs, error, &res); if(g_h == NULL || res != SCAP_SUCCESS) diff --git a/userspace/libsinsp/examples/test.cpp b/userspace/libsinsp/examples/test.cpp index f981e71239..ef4ad8e95c 100644 --- a/userspace/libsinsp/examples/test.cpp +++ b/userspace/libsinsp/examples/test.cpp @@ -64,17 +64,6 @@ static void usage() Overview: Goal of sinsp-example binary is to test and debug sinsp functionality and print events to STDOUT. All drivers are supported. Options: -<<<<<<< HEAD - -h, --help Print this page. - -f , --filter Filter string for events (see https://falco.org/docs/rules/supported-fields/ for supported fields). - -j, --json Use JSON as the output format (STDOUT). - -a, --all-threads Output information about all threads, not just the main one. - -e , --engine Specify the engine name to open possible values are: "kmod", "bpf", "udig", "nodriver", "savefile", "gvisor", "modern_bpf", "test_input". - -b , --bpf-path BPF probe path. - -d , --buffer-dim Buffer dimension. - -s , --file-path Scap file path. - -o , --output-fields-json [JSON support only, can also use without -j] Output fields string (see for supported display fields) that overwrites JSON default output fields for all events. * at the beginning prints JSON keys with null values, else no null fields are printed. -======= -h, --help Print this page. -f , --filter Filter string for events (see https://falco.org/docs/rules/supported-fields/ for supported fields). -j, --json Use JSON as the output format. @@ -84,7 +73,7 @@ Overview: Goal of sinsp-example binary is to test and debug sinsp functionality -k, --kmod Kernel module -s , --scap_file Scap file -d , --buffer_dim Buffer dimension. ->>>>>>> 06e716b3 (fix(libscap/libsinsp): allow examples to work correctly) + -o , --output-fields-json [JSON support only, can also use without -j] Output fields string (see for supported display fields) that overwrites JSON default output fields for all events. * at the beginning prints JSON keys with null values, else no null fields are printed. )"; cout << usage << endl; } diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index 93d76c4609..d8592b5f00 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -461,7 +461,7 @@ void sinsp::mark_ppm_sc_of_interest(uint32_t ppm_sc, bool enable) } if (ppm_sc >= PPM_SC_MAX || ppm_sc < 0) { - throw sinsp_exception("unexistent ppm_sc code: " + std::to_string(ppm_sc)); + throw sinsp_exception("inexistent ppm_sc code: " + std::to_string(ppm_sc)); } int ret = scap_set_eventmask(m_h, ppm_sc, enable); if (ret != SCAP_SUCCESS) From 3d2d1ca85c44dc7373fa75f60de35bb9e531363e Mon Sep 17 00:00:00 2001 From: Federico Di Pierro Date: Thu, 1 Sep 2022 16:59:49 +0200 Subject: [PATCH 29/29] fix(userspace/libscap): use correct idx when accessing routing table. Moreover, give more meaningful names to idx. Signed-off-by: Federico Di Pierro Co-authored-by: Luca Guerra --- userspace/libscap/scap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index 409f6ce173..ea61e9c1b6 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1178,15 +1178,15 @@ int scap_get_modifies_state_ppm_sc(uint32_t* ppm_sc_array) #ifdef __linux__ // Collect EF_MODIFIES_STATE events - for (int i = 0; i < PPM_EVENT_MAX; i++) + for (int event_nr = 0; event_nr < PPM_EVENT_MAX; event_nr++) { - if (g_event_info[i].flags & EF_MODIFIES_STATE) + if (g_event_info[event_nr].flags & EF_MODIFIES_STATE) { - for (int j = 0; j < SYSCALL_TABLE_SIZE; j++) + for (int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - if (g_syscall_table[j].exit_event_type == i || g_syscall_table[j].enter_event_type == i) + if (g_syscall_table[syscall_nr].exit_event_type == event_nr || g_syscall_table[syscall_nr].enter_event_type == event_nr) { - uint32_t ppm_sc_code = g_syscall_code_routing_table[i]; + uint32_t ppm_sc_code = g_syscall_code_routing_table[syscall_nr]; ppm_sc_array[ppm_sc_code] = 1; } } @@ -1194,11 +1194,11 @@ int scap_get_modifies_state_ppm_sc(uint32_t* ppm_sc_array) } // Collect UF_NEVER_DROP syscalls - for (int j = 0; j < SYSCALL_TABLE_SIZE; j++) + for (int syscall_nr = 0; syscall_nr < SYSCALL_TABLE_SIZE; syscall_nr++) { - if (g_syscall_table[j].flags & UF_NEVER_DROP) + if (g_syscall_table[syscall_nr].flags & UF_NEVER_DROP) { - uint32_t ppm_sc_code = g_syscall_code_routing_table[j]; + uint32_t ppm_sc_code = g_syscall_code_routing_table[syscall_nr]; ppm_sc_array[ppm_sc_code] = 1; } }