diff --git a/driver/main.c b/driver/main.c index 8dede0b79a..b83678d65c 100644 --- a/driver/main.c +++ b/driver/main.c @@ -525,7 +525,7 @@ static int ppm_open(struct inode *inode, struct file *filp) consumer->fullcapture_port_range_start = 0; consumer->fullcapture_port_range_end = 0; consumer->statsd_port = PPM_PORT_STATSD; - bitmap_fill(consumer->events_mask, PPM_EVENT_MAX); /* Enable all syscall to be passed to userspace */ + bitmap_fill(consumer->syscalls_mask, SYSCALL_TABLE_SIZE); /* Enable all syscalls to be passed to userspace */ reset_ring_buffer(ring); ring->open = true; @@ -1051,49 +1051,45 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ret = 0; goto cleanup_ioctl; } - case PPM_IOCTL_MASK_ZERO_EVENTS: + case PPM_IOCTL_ZERO_SYSCALLS: { - vpr_info("PPM_IOCTL_MASK_ZERO_EVENTS, consumer %p\n", consumer_id); + vpr_info("PPM_IOCTL_ZERO_SYSCALLS, consumer %p\n", consumer_id); - bitmap_zero(consumer->events_mask, PPM_EVENT_MAX); - - /* Used for dropping events so they must stay on */ - set_bit(PPME_DROP_E, consumer->events_mask); - set_bit(PPME_DROP_X, consumer->events_mask); + bitmap_zero(consumer->syscalls_mask, SYSCALL_TABLE_SIZE); ret = 0; goto cleanup_ioctl; } - case PPM_IOCTL_MASK_SET_EVENT: + case PPM_IOCTL_ENABLE_SYSCALL: { - u32 syscall_to_set = (u32)arg; + u32 syscall_to_set = (u32)arg - SYSCALL_TABLE_ID0; - vpr_info("PPM_IOCTL_MASK_SET_EVENT (%u), consumer %p\n", syscall_to_set, consumer_id); + vpr_info("PPM_IOCTL_ENABLE_SYSCALL (%u), consumer %p\n", syscall_to_set, consumer_id); - if (syscall_to_set >= PPM_EVENT_MAX) { + if (syscall_to_set >= SYSCALL_TABLE_SIZE) { pr_err("invalid syscall %u\n", syscall_to_set); ret = -EINVAL; goto cleanup_ioctl; } - set_bit(syscall_to_set, consumer->events_mask); + set_bit(syscall_to_set, consumer->syscalls_mask); ret = 0; goto cleanup_ioctl; } - case PPM_IOCTL_MASK_UNSET_EVENT: + case PPM_IOCTL_DISABLE_SYSCALL: { - u32 syscall_to_unset = (u32)arg; + u32 syscall_to_unset = (u32)arg - SYSCALL_TABLE_ID0; - vpr_info("PPM_IOCTL_MASK_UNSET_EVENT (%u), consumer %p\n", syscall_to_unset, consumer_id); + vpr_info("PPM_IOCTL_DISABLE_SYSCALL (%u), consumer %p\n", syscall_to_unset, consumer_id); - if (syscall_to_unset >= PPM_EVENT_MAX) { + if (syscall_to_unset >= SYSCALL_TABLE_SIZE) { pr_err("invalid syscall %u\n", syscall_to_unset); ret = -EINVAL; goto cleanup_ioctl; } - clear_bit(syscall_to_unset, consumer->events_mask); + clear_bit(syscall_to_unset, consumer->syscalls_mask); ret = 0; goto cleanup_ioctl; @@ -1778,14 +1774,22 @@ static int record_event_consumer(struct ppm_consumer_t *consumer, int drop = 1; int32_t cbres = PPM_SUCCESS; int cpu; + long table_index; if (tp_type < TP_VAL_INTERNAL && !(consumer->tracepoints_attached & (1 << tp_type))) { return res; } - if (!test_bit(event_type, consumer->events_mask)) - return res; + // Check if syscall is interesting for the consumer + if (event_datap->category == PPMC_SYSCALL) + { + table_index = event_datap->event_info.syscall_data.id - SYSCALL_TABLE_ID0; + if (!test_bit(table_index, consumer->syscalls_mask)) + { + return res; + } + } if (event_type != PPME_DROP_E && event_type != PPME_DROP_X) { if (consumer->need_to_insert_drop_e == 1) diff --git a/driver/ppm.h b/driver/ppm.h index b71cf1722c..8d04bb1cb9 100644 --- a/driver/ppm.h +++ b/driver/ppm.h @@ -77,7 +77,7 @@ struct ppm_consumer_t { uint16_t fullcapture_port_range_end; uint16_t statsd_port; unsigned long buffer_bytes_dim; /* Every consumer will have its per-CPU buffer dim in bytes. */ - DECLARE_BITMAP(events_mask, PPM_EVENT_MAX); + DECLARE_BITMAP(syscalls_mask, SYSCALL_TABLE_SIZE); u32 tracepoints_attached; }; #endif // UDIG diff --git a/driver/ppm_events_public.h b/driver/ppm_events_public.h index b2180c4d01..1f38647b57 100644 --- a/driver/ppm_events_public.h +++ b/driver/ppm_events_public.h @@ -1792,9 +1792,9 @@ struct ppm_evt_hdr { #define PPM_IOCTL_DISABLE_DROPPING_MODE _IO(PPM_IOCTL_MAGIC, 2) #define PPM_IOCTL_ENABLE_DROPPING_MODE _IO(PPM_IOCTL_MAGIC, 3) #define PPM_IOCTL_SET_SNAPLEN _IO(PPM_IOCTL_MAGIC, 4) -#define PPM_IOCTL_MASK_ZERO_EVENTS _IO(PPM_IOCTL_MAGIC, 5) -#define PPM_IOCTL_MASK_SET_EVENT _IO(PPM_IOCTL_MAGIC, 6) -#define PPM_IOCTL_MASK_UNSET_EVENT _IO(PPM_IOCTL_MAGIC, 7) +// #define PPM_IOCTL_MASK_ZERO_EVENTS _IO(PPM_IOCTL_MAGIC, 5) Support dropped +// #define PPM_IOCTL_MASK_SET_EVENT _IO(PPM_IOCTL_MAGIC, 6) Support dropped +// #define PPM_IOCTL_MASK_UNSET_EVENT _IO(PPM_IOCTL_MAGIC, 7) Support dropped #define PPM_IOCTL_DISABLE_DYNAMIC_SNAPLEN _IO(PPM_IOCTL_MAGIC, 8) #define PPM_IOCTL_ENABLE_DYNAMIC_SNAPLEN _IO(PPM_IOCTL_MAGIC, 9) #define PPM_IOCTL_GET_VTID _IO(PPM_IOCTL_MAGIC, 10) @@ -1815,6 +1815,9 @@ struct ppm_evt_hdr { #define PPM_IOCTL_GET_SCHEMA_VERSION _IO(PPM_IOCTL_MAGIC, 25) #define PPM_IOCTL_MANAGE_TP _IO(PPM_IOCTL_MAGIC, 26) #define PPM_IOCTL_GET_TPMASK _IO(PPM_IOCTL_MAGIC, 27) +#define PPM_IOCTL_ZERO_SYSCALLS _IO(PPM_IOCTL_MAGIC, 28) // this replaces PPM_IOCTL_MASK_ZERO_EVENTS +#define PPM_IOCTL_ENABLE_SYSCALL _IO(PPM_IOCTL_MAGIC, 29) // this replaces PPM_IOCTL_MASK_SET_EVENT +#define PPM_IOCTL_DISABLE_SYSCALL _IO(PPM_IOCTL_MAGIC, 30) // this replaces PPM_IOCTL_MASK_UNSET_EVENT #endif // CYGWING_AGENT extern const struct ppm_name_value socket_families[]; diff --git a/driver/syscall_table.c b/driver/syscall_table.c index 1a7d4e7bfb..b0ca1a8ff8 100644 --- a/driver/syscall_table.c +++ b/driver/syscall_table.c @@ -68,6 +68,7 @@ or GPL2.txt for full copies of the license. /* * SYSCALL TABLE + * FIXME: kmod only supports SYSCALL_TABLE_ID0 */ const struct syscall_evt_pair g_syscall_table[SYSCALL_TABLE_SIZE] = { #ifdef __NR_open diff --git a/userspace/libscap/engine/bpf/scap_bpf.c b/userspace/libscap/engine/bpf/scap_bpf.c index e1cba796bf..0bee8f3acd 100644 --- a/userspace/libscap/engine/bpf/scap_bpf.c +++ b/userspace/libscap/engine/bpf/scap_bpf.c @@ -953,7 +953,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; - return set_single_syscall_of_interest(handle, ppm_sc, op == SCAP_EVENTMASK_SET); + return set_single_syscall_of_interest(handle, ppm_sc, op == SCAP_PPM_SC_MASK_SET); } static int32_t populate_event_table_map(struct bpf_engine *handle) @@ -1689,15 +1689,15 @@ static int32_t scap_bpf_handle_event_mask(struct scap_engine_handle engine, uint int32_t ret = SCAP_SUCCESS; switch(op) { - case SCAP_EVENTMASK_ZERO: + case SCAP_PPM_SC_MASK_ZERO: for(ppm_sc = 0; ppm_sc < PPM_SC_MAX && ret==SCAP_SUCCESS; ppm_sc++) { - ret = update_interesting_syscalls_map(engine, SCAP_EVENTMASK_UNSET, ppm_sc); + ret = update_interesting_syscalls_map(engine, SCAP_PPM_SC_MASK_UNSET, ppm_sc); } break; - case SCAP_EVENTMASK_SET: - case SCAP_EVENTMASK_UNSET: + case SCAP_PPM_SC_MASK_SET: + case SCAP_PPM_SC_MASK_UNSET: ret = update_interesting_syscalls_map(engine, op, ppm_sc); break; diff --git a/userspace/libscap/engine/kmod/scap_kmod.c b/userspace/libscap/engine/kmod/scap_kmod.c index a30df759ff..6a03bdefe6 100644 --- a/userspace/libscap/engine/kmod/scap_kmod.c +++ b/userspace/libscap/engine/kmod/scap_kmod.c @@ -165,41 +165,30 @@ int32_t scap_kmod_handle_tp_mask(struct scap_engine_handle engine, uint32_t op, return SCAP_SUCCESS; } -/// TODO: it would be better 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) + if (op != SCAP_PPM_SC_MASK_ZERO) { - int ioctl_op = op == SCAP_EVENTMASK_SET ? PPM_IOCTL_MASK_SET_EVENT : PPM_IOCTL_MASK_UNSET_EVENT; + int ioctl_op = op == SCAP_PPM_SC_MASK_SET ? PPM_IOCTL_ENABLE_SYSCALL : PPM_IOCTL_DISABLE_SYSCALL; // 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_table[i].ppm_sc == 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)) + if(ioctl(devset->m_devs[0].m_fd, ioctl_op, i)) { ASSERT(false); return scap_errprintf(engine.m_handle->m_lasterr, errno, - "%s(%d) failed for event type %d", - __FUNCTION__, op, enter_ev); - } - if(ioctl(devset->m_devs[0].m_fd, ioctl_op, exit_ev)) - { - ASSERT(false); - return scap_errprintf(engine.m_handle->m_lasterr, errno, - "%s(%d) failed for event type %d", - __FUNCTION__, op, exit_ev); + "%s(%d) failed for syscall %d", + __FUNCTION__, op, i); } } } } else { - if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_MASK_ZERO_EVENTS, 0)) + if(ioctl(devset->m_devs[0].m_fd, PPM_IOCTL_ZERO_SYSCALLS, 0)) { ASSERT(false); return scap_errprintf(engine.m_handle->m_lasterr, errno, @@ -401,7 +390,7 @@ 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++) { - uint32_t op = oargs->ppm_sc_of_interest.ppm_sc[ppm_sc] ? SCAP_EVENTMASK_SET : SCAP_EVENTMASK_UNSET; + uint32_t op = oargs->ppm_sc_of_interest.ppm_sc[ppm_sc] ? SCAP_PPM_SC_MASK_SET : SCAP_PPM_SC_MASK_UNSET; scap_kmod_handle_event_mask(engine, op, ppm_sc); } diff --git a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c index 641054cffa..07bdb24383 100644 --- a/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c +++ b/userspace/libscap/engine/modern_bpf/scap_modern_bpf.c @@ -159,11 +159,11 @@ static int32_t scap_modern_bpf__configure(struct scap_engine_handle engine, enum pman_set_snaplen(arg1); case SCAP_EVENTMASK: /* We use this setting just to modify the interesting syscalls. */ - if(arg1 == SCAP_EVENTMASK_SET || arg1 == SCAP_EVENTMASK_UNSET) + if(arg1 == SCAP_PPM_SC_MASK_SET || arg1 == SCAP_PPM_SC_MASK_UNSET) { - update_single_64bit_syscall_of_interest(arg2, arg1 == SCAP_EVENTMASK_SET); + update_single_64bit_syscall_of_interest(arg2, arg1 == SCAP_PPM_SC_MASK_SET); } - else if(arg1 == SCAP_EVENTMASK_ZERO) + else if(arg1 == SCAP_PPM_SC_MASK_ZERO) { pman_clean_all_64bit_interesting_syscalls(); } diff --git a/userspace/libscap/scap.c b/userspace/libscap/scap.c index f8c8ae7c34..dc17c9999f 100644 --- a/userspace/libscap/scap.c +++ b/userspace/libscap/scap.c @@ -1391,7 +1391,7 @@ 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) +static int32_t scap_handle_ppm_sc_mask(scap_t* handle, uint32_t op, uint32_t ppm_sc) { if(handle == NULL) { @@ -1400,9 +1400,9 @@ static int32_t scap_handle_eventmask(scap_t* handle, uint32_t op, uint32_t ppm_s switch(op) { - case SCAP_EVENTMASK_SET: - case SCAP_EVENTMASK_UNSET: - case SCAP_EVENTMASK_ZERO: + case SCAP_PPM_SC_MASK_SET: + case SCAP_PPM_SC_MASK_UNSET: + case SCAP_PPM_SC_MASK_ZERO: break; default: @@ -1432,12 +1432,12 @@ static int32_t scap_handle_eventmask(scap_t* handle, uint32_t op, uint32_t ppm_s #endif // HAS_CAPTURE } -int32_t scap_clear_eventmask(scap_t* handle) { - return(scap_handle_eventmask(handle, SCAP_EVENTMASK_ZERO, 0)); +int32_t scap_clear_ppm_sc_mask(scap_t* handle) { + return(scap_handle_ppm_sc_mask(handle, SCAP_PPM_SC_MASK_ZERO, 0)); } -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)); +int32_t scap_set_ppm_sc(scap_t* handle, uint32_t ppm_sc, bool enabled) { + return(scap_handle_ppm_sc_mask(handle, enabled ? SCAP_PPM_SC_MASK_SET : SCAP_PPM_SC_MASK_UNSET, ppm_sc)); } static int32_t scap_handle_tpmask(scap_t* handle, uint32_t op, uint32_t tp) diff --git a/userspace/libscap/scap.def b/userspace/libscap/scap.def index c9976ea14e..0212d47288 100644 --- a/userspace/libscap/scap.def +++ b/userspace/libscap/scap.def @@ -36,8 +36,8 @@ EXPORTS scap_free_userlist scap_set_snaplen scap_get_readfile_offset - scap_clear_eventmask - scap_set_eventmask + scap_clear_ppm_sc_mask + scap_set_ppm_sc scap_set_tpmask scap_number_of_bytes_to_write scap_event_get_dump_flags diff --git a/userspace/libscap/scap.h b/userspace/libscap/scap.h index 5c87fe4544..8755b6feb9 100644 --- a/userspace/libscap/scap.h +++ b/userspace/libscap/scap.h @@ -957,31 +957,33 @@ const scap_machine_info* scap_get_machine_info(scap_t* handle); int32_t scap_set_snaplen(scap_t* handle, uint32_t snaplen); /*! - \brief Clear the event mask: no events will be passed + \brief Clear the syscall mask: no syscalls events will be passed pushed to userspace. \param handle Handle to the capture instance. \note This function can only be called for live captures. */ -int32_t scap_clear_eventmask(scap_t* handle); +int32_t scap_clear_ppm_sc_mask(scap_t* handle); /*! - \brief Set the ppm_sc into the eventmask so that - users can receive the related syscalls. Useful for offloading + \brief (Un)Set the ppm_sc bit in the syscall mask so that + users can (drop)receive the related syscall. Useful for offloading operations such as evt.type=open \param handle Handle to the capture instance. \param ppm_sc id (example PPM_SC_EXECVE) + \param enabled whether to enable or disable the syscall \note This function can only be called for live captures. */ -int32_t scap_set_eventmask(scap_t* handle, uint32_t ppm_sc, bool enabled); +int32_t scap_set_ppm_sc(scap_t* handle, uint32_t ppm_sc, bool enabled); /*! - \brief Set the tp into the tpmask so that - users can attach the related tracepoint. + \brief (Un)Set the tp into the tracepoint mask so that + users can (detach)attach the requested tracepoint. \param handle Handle to the capture instance. \param tp id (example SYS_ENTER) + \param enabled whether to enable or disable the tracepoint \note This function can only be called for live captures. */ int32_t scap_set_tpmask(scap_t* handle, uint32_t tp, bool enabled); diff --git a/userspace/libscap/scap_vtable.h b/userspace/libscap/scap_vtable.h index 1ef54d5dd1..fc483be44d 100644 --- a/userspace/libscap/scap_vtable.h +++ b/userspace/libscap/scap_vtable.h @@ -30,22 +30,15 @@ struct scap_stats; typedef struct scap scap_t; typedef struct ppm_evt_hdr scap_evt; -/* - * magic constants, matching the kmod-only ioctl numbers defined as: -#define PPM_IOCTL_MAGIC 's' -#define PPM_IOCTL_MASK_ZERO_EVENTS _IO(PPM_IOCTL_MAGIC, 5) -#define PPM_IOCTL_MASK_SET_EVENT _IO(PPM_IOCTL_MAGIC, 6) -#define PPM_IOCTL_MASK_UNSET_EVENT _IO(PPM_IOCTL_MAGIC, 7) - */ enum scap_eventmask_op { - SCAP_EVENTMASK_ZERO = 0x7305, //< disable all events - SCAP_EVENTMASK_SET = 0x7306, //< enable an event - SCAP_EVENTMASK_UNSET = 0x7307, //< disable an event + SCAP_PPM_SC_MASK_ZERO = 0, //< disable all syscalls + SCAP_PPM_SC_MASK_SET = 1, //< enable a syscall + SCAP_PPM_SC_MASK_UNSET = 2, //< disable a syscall }; enum scap_tpmask_op { - SCAP_TPMASK_SET = 0x8306, //< enable a tp - SCAP_TPMASK_UNSET = 0x8307, //< disable a tp + SCAP_TPMASK_SET = 0, //< enable a tp + SCAP_TPMASK_UNSET = 1, //< disable a tp }; /** diff --git a/userspace/libsinsp/sinsp_ppm_sc.cpp b/userspace/libsinsp/sinsp_ppm_sc.cpp index 5ec2bbe23a..9fa07e9b55 100644 --- a/userspace/libsinsp/sinsp_ppm_sc.cpp +++ b/userspace/libsinsp/sinsp_ppm_sc.cpp @@ -44,7 +44,7 @@ void sinsp::mark_ppm_sc_of_interest(uint32_t ppm_sc, bool enable) { throw sinsp_exception("inexistent ppm_sc code: " + std::to_string(ppm_sc)); } - int ret = scap_set_eventmask(m_h, ppm_sc, enable); + int ret = scap_set_ppm_sc(m_h, ppm_sc, enable); if (ret != SCAP_SUCCESS) { throw sinsp_exception(scap_getlasterr(m_h));