From f8f0af68ada92e61c41acb972125fc0fceec3eb1 Mon Sep 17 00:00:00 2001 From: Raphael Campos Date: Fri, 31 Jan 2025 12:55:55 -0600 Subject: [PATCH 1/2] feat: allow different field names - Allow any field name in the in-kernel string filter. - Currently, only one string-type field name is supported. - Future support for multiple field names is planned. --- pkg/filters/data.go | 70 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/pkg/filters/data.go b/pkg/filters/data.go index a347d33a8939..cb7b1b49c9f0 100644 --- a/pkg/filters/data.go +++ b/pkg/filters/data.go @@ -44,6 +44,17 @@ func (kdf *KernelDataFilter) IsKernelFilterEnabled(field string) bool { return false } +// getKernelFieldName return only one field name with in-kernel filter +// TODO: need to retrieve all possible field names (and not only one) +func (kdf *KernelDataFilter) getKernelFieldName() string { + var key string + for k := range kdf.kernelFilters { + key = k + break + } + return key +} + type DataFilter struct { filters map[string]Filter[*StringFilter] kernelDataFilter *KernelDataFilter @@ -61,6 +72,48 @@ func NewDataFilter() *DataFilter { } } +// list of events and field names allowed to have in-kernel filter +var allowedKernelField = map[events.ID]string{ + // LSM hooks + events.SecurityBprmCheck: "pathname", // 0 + events.SecurityFileOpen: "pathname", // 0 + events.SecurityInodeUnlink: "pathname", // 0 + events.SecuritySbMount: "path", // 1 + events.SecurityBPFMap: "map_name", // 1 + events.SecurityKernelReadFile: "pathname", // 0 + events.SecurityInodeMknod: "file_name", // 0 + events.SecurityPostReadFile: "pathname", // 0 + events.SecurityInodeSymlinkEventId: "linkpath", // 0 + events.SecurityMmapFile: "pathname", // 0 + events.SecurityFileMprotect: "pathname", // 0 + events.SecurityInodeRename: "old_path", // 0 + events.SecurityBpfProg: "name", // 1 + events.SecurityPathNotify: "pathname", // 0 + events.SharedObjectLoaded: "pathname", // 0 + // Syscalls + events.Execve: "pathname", + events.Execveat: "pathname", + // Others + events.ModuleLoad: "pathname", + events.InotifyWatch: "pathname", + events.DoTruncate: "pathname", + events.MagicWrite: "pathname", + events.VfsUtimes: "pathname", + events.LoadElfPhdrs: "pathname", + events.CallUsermodeHelper: "pathname", + events.ChmodCommon: "pathname", + events.DoMmap: "pathname", +} + +// checkAvailabilityKernelFilter check if event ID and field name are allowed to be an kernel filter +func (f *DataFilter) checkAvailabilityKernelFilter(event events.ID, field string) bool { + if selectedField := allowedKernelField[event]; selectedField != field { + return false + } + + return true +} + func (f *DataFilter) Equalities() (StringFilterEqualities, error) { if !f.Enabled() { return StringFilterEqualities{ @@ -73,8 +126,9 @@ func (f *DataFilter) Equalities() (StringFilterEqualities, error) { }, nil } - // selected data name - dataField := "pathname" + // get the field name for in-kernel filter + // TODO: only one allowed at the moment (more to come) + dataField := f.kernelDataFilter.getKernelFieldName() fieldName, ok := f.filters[dataField] if !ok { @@ -166,12 +220,10 @@ func (f *DataFilter) Parse(id events.ID, fieldName string, operatorAndValues str // valueHandler is passed to the filter constructor to allow for custom value handling // before the filter is applied valueHandler := func(val string) (string, error) { - switch id { - case events.SecurityFileOpen, - events.MagicWrite, - events.SecurityMmapFile: + if f.checkAvailabilityKernelFilter(id, fieldName) { return f.processKernelFilter(val, fieldName) - + } + switch id { case events.SysEnter, events.SysExit, events.SuspiciousSyscallSource, @@ -280,10 +332,6 @@ func (f *DataFilter) checkKernelFilterRestrictions(val string) error { // enableKernelFilterArg activates a kernel filter for the specified data field. // This function currently supports enabling filters for the "pathname" field only. func (f *DataFilter) enableKernelFilterArg(fieldName string) { - if fieldName != "pathname" { - return - } - filter, ok := f.filters[fieldName] if !ok { return From 41b8fa0d7918f448951069f2d37b3720597fdfb6 Mon Sep 17 00:00:00 2001 From: Raphael Campos Date: Fri, 31 Jan 2025 12:56:37 -0600 Subject: [PATCH 2/2] feat: extend string data filtering for other events --- pkg/ebpf/c/common/context.h | 1 + pkg/ebpf/c/tracee.bpf.c | 77 +++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/pkg/ebpf/c/common/context.h b/pkg/ebpf/c/common/context.h index 5732173c198d..60c42042260a 100644 --- a/pkg/ebpf/c/common/context.h +++ b/pkg/ebpf/c/common/context.h @@ -259,6 +259,7 @@ statfunc bool reset_event(event_data_t *event, u32 event_id) event->config.field_types = event_config->field_types; event->config.submit_for_policies = event_config->submit_for_policies; event->context.matched_policies = event_config->submit_for_policies; + event->config.data_filter = event_config->data_filter; return true; } diff --git a/pkg/ebpf/c/tracee.bpf.c b/pkg/ebpf/c/tracee.bpf.c index f53272fc5bea..e9f837c26353 100644 --- a/pkg/ebpf/c/tracee.bpf.c +++ b/pkg/ebpf/c/tracee.bpf.c @@ -387,6 +387,9 @@ int syscall__execve_enter(void *ctx) &p.event->args_buf, (const char *const *) sys->args.args[2] /*envp*/, 2); } + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -417,6 +420,9 @@ int syscall__execve_exit(void *ctx) &p.event->args_buf, (const char *const *) sys->args.args[2] /*envp*/, 2); } + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, sys->ret); } @@ -447,6 +453,9 @@ int syscall__execveat_enter(void *ctx) } save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[4] /*flags*/, sizeof(int), 4); + if (!evaluate_data_filters(&p, 1)) + return 0; + return events_perf_submit(&p, 0); } @@ -479,6 +488,9 @@ int syscall__execveat_exit(void *ctx) } save_to_submit_buf(&p.event->args_buf, (void *) &sys->args.args[4] /*flags*/, sizeof(int), 4); + if (!evaluate_data_filters(&p, 1)) + return 0; + return events_perf_submit(&p, sys->ret); } @@ -1714,6 +1726,9 @@ int BPF_KPROBE(trace_call_usermodehelper) save_str_arr_to_buf(&p.event->args_buf, (const char *const *) envp, 2); save_to_submit_buf(&p.event->args_buf, (void *) &wait, sizeof(int), 3); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -2272,6 +2287,9 @@ int BPF_KPROBE(trace_security_bprm_check) if (p.config->options & OPT_EXEC_ENV) save_str_arr_to_buf(&p.event->args_buf, envp, 4); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -2347,6 +2365,9 @@ int BPF_KPROBE(trace_security_sb_mount) save_str_to_buf(&p.event->args_buf, (void *) type, 2); save_to_submit_buf(&p.event->args_buf, &flags, sizeof(unsigned long), 3); + if (!evaluate_data_filters(&p, 1)) + return 0; + return events_perf_submit(&p, 0); } @@ -2381,6 +2402,9 @@ int BPF_KPROBE(trace_security_inode_unlink) save_to_submit_buf(&p.event->args_buf, &unlinked_file_id.device, sizeof(dev_t), 2); save_to_submit_buf(&p.event->args_buf, &unlinked_file_id.ctime, sizeof(u64), 3); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -2580,6 +2604,9 @@ int BPF_KPROBE(trace_security_inode_symlink) save_str_to_buf(&p.event->args_buf, dentry_path, 0); save_str_to_buf(&p.event->args_buf, (void *) old_name, 1); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -3610,6 +3637,9 @@ int BPF_KPROBE(trace_ret_do_mmap) save_to_submit_buf(&p.event->args_buf, &prot, sizeof(unsigned long), 8); save_to_submit_buf(&p.event->args_buf, &mmap_flags, sizeof(unsigned long), 9); + if (!evaluate_data_filters(&p, 1)) + return 0; + return events_perf_submit(&p, 0); } @@ -3643,6 +3673,9 @@ int BPF_KPROBE(trace_security_mmap_file) save_to_submit_buf(&p.event->args_buf, &inode_nr, sizeof(unsigned long), 3); save_to_submit_buf(&p.event->args_buf, &ctime, sizeof(u64), 4); + if (!evaluate_data_filters(&p, 0)) + return 0; + events_perf_submit(&p, 0); } @@ -3711,6 +3744,9 @@ int BPF_KPROBE(trace_security_file_mprotect) save_to_submit_buf(&p.event->args_buf, &pkey, sizeof(int), 6); } + if (!evaluate_data_filters(&p, 0)) + return 0; + events_perf_submit(&p, 0); } @@ -3953,6 +3989,9 @@ int BPF_KPROBE(trace_security_bpf_map) // 2nd argument == map_name (const char *) save_str_to_buf(&p.event->args_buf, (void *) __builtin_preserve_access_index(&map->name), 1); + if (!evaluate_data_filters(&p, 1)) + return 0; + return events_perf_submit(&p, 0); } @@ -4008,6 +4047,9 @@ int BPF_KPROBE(trace_security_bpf_prog) save_to_submit_buf(&p.event->args_buf, &prog_id, sizeof(u32), 3); save_to_submit_buf(&p.event->args_buf, &is_load, sizeof(bool), 4); + if (!evaluate_data_filters(&p, 1)) + return 0; + events_perf_submit(&p, 0); return 0; @@ -4149,6 +4191,9 @@ int BPF_KPROBE(trace_security_kernel_read_file) save_to_submit_buf(&p.event->args_buf, &type_id, sizeof(int), 3); save_to_submit_buf(&p.event->args_buf, &ctime, sizeof(u64), 4); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -4173,6 +4218,10 @@ int BPF_KPROBE(trace_security_kernel_post_read_file) save_str_to_buf(&p.event->args_buf, file_path, 0); save_to_submit_buf(&p.event->args_buf, &size, sizeof(loff_t), 1); save_to_submit_buf(&p.event->args_buf, &type_id, sizeof(int), 2); + + if (!evaluate_data_filters(&p, 0)) + return 0; + events_perf_submit(&p, 0); } @@ -4221,6 +4270,9 @@ int BPF_KPROBE(trace_security_inode_mknod) save_to_submit_buf(&p.event->args_buf, &mode, sizeof(unsigned short), 1); save_to_submit_buf(&p.event->args_buf, &dev, sizeof(dev_t), 2); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -4463,6 +4515,9 @@ int tracepoint__module__module_load(struct bpf_raw_tracepoint_args *ctx) save_str_to_buf(&p.event->args_buf, (void *) version, 1); save_str_to_buf(&p.event->args_buf, (void *) srcversion, 2); + if (!evaluate_data_filters(&p, 3)) + return 0; + return events_perf_submit(&p, 0); } @@ -4571,6 +4626,10 @@ int BPF_KPROBE(trace_load_elf_phdrs) save_str_to_buf(&p.event->args_buf, (void *) elf_pathname, 0); save_to_submit_buf(&p.event->args_buf, &proc_info->interpreter.id.device, sizeof(dev_t), 1); save_to_submit_buf(&p.event->args_buf, &proc_info->interpreter.id.inode, sizeof(unsigned long), 2); + + if (!evaluate_data_filters(&p, 0)) + return 0; + events_perf_submit(&p, 0); return 0; @@ -4678,6 +4737,9 @@ int BPF_KPROBE(trace_security_inode_rename) void *new_dentry_path = get_dentry_path_str(new_dentry); save_str_to_buf(&p.event->args_buf, new_dentry_path, 1); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -4816,6 +4878,9 @@ statfunc int common_utimes(struct pt_regs *ctx) save_to_submit_buf(&p.event->args_buf, &atime, sizeof(u64), 3); save_to_submit_buf(&p.event->args_buf, &mtime, sizeof(u64), 4); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -4853,6 +4918,9 @@ int BPF_KPROBE(trace_do_truncate) save_to_submit_buf(&p.event->args_buf, &dev, sizeof(dev_t), 2); save_to_submit_buf(&p.event->args_buf, &length, sizeof(u64), 3); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -5043,6 +5111,9 @@ int BPF_KPROBE(trace_ret_inotify_find_inode) save_to_submit_buf(&p.event->args_buf, &inode_nr, sizeof(unsigned long), 1); save_to_submit_buf(&p.event->args_buf, &dev, sizeof(dev_t), 2); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -5197,6 +5268,9 @@ int BPF_KPROBE(trace_security_path_notify) save_to_submit_buf(&p.event->args_buf, &mask, sizeof(u64), 3); save_to_submit_buf(&p.event->args_buf, &obj_type, sizeof(unsigned int), 4); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); } @@ -5300,6 +5374,9 @@ int BPF_KPROBE(trace_chmod_common) save_str_to_buf(&p.event->args_buf, file_path, 0); save_to_submit_buf(&p.event->args_buf, &mode, sizeof(umode_t), 1); + if (!evaluate_data_filters(&p, 0)) + return 0; + return events_perf_submit(&p, 0); }