From abadd93bb90e251a7d00418860724095e7c59948 Mon Sep 17 00:00:00 2001 From: Mauro Ezequiel Moltrasio Date: Thu, 19 Feb 2026 18:03:51 +0100 Subject: [PATCH] refactor(bpf): hide path_hooks_support_bpf_d_path Make the decision of using `bpf_d_path` or our own `d_path` implementation transparent from the main LSM hook functions. Instead, the decision is made inside the events and bound_path modules. --- fact-ebpf/src/bpf/bound_path.h | 14 ++++++------ fact-ebpf/src/bpf/events.h | 39 +++++++++++++++++++++------------- fact-ebpf/src/bpf/main.c | 37 +++++++++----------------------- fact-ebpf/src/bpf/maps.h | 1 - 4 files changed, 40 insertions(+), 51 deletions(-) diff --git a/fact-ebpf/src/bpf/bound_path.h b/fact-ebpf/src/bpf/bound_path.h index 8002405..7a2091f 100644 --- a/fact-ebpf/src/bpf/bound_path.h +++ b/fact-ebpf/src/bpf/bound_path.h @@ -11,6 +11,8 @@ #include // clang-format on +volatile const bool path_hooks_support_bpf_d_path; + __always_inline static char* path_safe_access(char* p, unsigned int offset) { return &p[PATH_LEN_CLAMP(offset)]; } @@ -36,20 +38,16 @@ __always_inline static struct bound_path_t* _path_read(struct path* path, bound_ return bound_path; } -__always_inline static struct bound_path_t* path_read(struct path* path) { +__always_inline static struct bound_path_t* path_read_unchecked(struct path* path) { return _path_read(path, BOUND_PATH_MAIN, true); } -__always_inline static struct bound_path_t* path_read_no_d_path(struct path* path) { - return _path_read(path, BOUND_PATH_MAIN, false); +__always_inline static struct bound_path_t* path_read(struct path* path) { + return _path_read(path, BOUND_PATH_MAIN, path_hooks_support_bpf_d_path); } __always_inline static struct bound_path_t* path_read_alt(struct path* path) { - return _path_read(path, BOUND_PATH_ALTERNATE, true); -} - -__always_inline static struct bound_path_t* path_read_alt_no_d_path(struct path* path) { - return _path_read(path, BOUND_PATH_ALTERNATE, false); + return _path_read(path, BOUND_PATH_ALTERNATE, path_hooks_support_bpf_d_path); } enum path_append_status_t { diff --git a/fact-ebpf/src/bpf/events.h b/fact-ebpf/src/bpf/events.h index be1237c..abe4d19 100644 --- a/fact-ebpf/src/bpf/events.h +++ b/fact-ebpf/src/bpf/events.h @@ -3,6 +3,7 @@ // clang-format off #include "vmlinux.h" +#include "bound_path.h" #include "inode.h" #include "maps.h" #include "process.h" @@ -42,26 +43,36 @@ __always_inline static void __submit_event(struct event_t* event, bpf_ringbuf_discard(event, 0); } -__always_inline static void submit_event(struct metrics_by_hook_t* m, - file_activity_type_t event_type, - const char filename[PATH_MAX], - inode_key_t* inode, - bool use_bpf_d_path) { +__always_inline static void submit_open_event(struct metrics_by_hook_t* m, + file_activity_type_t event_type, + const char filename[PATH_MAX], + inode_key_t* inode) { + struct event_t* event = bpf_ringbuf_reserve(&rb, sizeof(struct event_t), 0); + if (event == NULL) { + m->ringbuffer_full++; + return; + } + + __submit_event(event, m, event_type, filename, inode, true); +} + +__always_inline static void submit_unlink_event(struct metrics_by_hook_t* m, + const char filename[PATH_MAX], + inode_key_t* inode) { struct event_t* event = bpf_ringbuf_reserve(&rb, sizeof(struct event_t), 0); if (event == NULL) { m->ringbuffer_full++; return; } - __submit_event(event, m, event_type, filename, inode, use_bpf_d_path); + __submit_event(event, m, FILE_ACTIVITY_UNLINK, filename, inode, path_hooks_support_bpf_d_path); } __always_inline static void submit_mode_event(struct metrics_by_hook_t* m, const char filename[PATH_MAX], inode_key_t* inode, umode_t mode, - umode_t old_mode, - bool use_bpf_d_path) { + umode_t old_mode) { struct event_t* event = bpf_ringbuf_reserve(&rb, sizeof(struct event_t), 0); if (event == NULL) { m->ringbuffer_full++; @@ -71,7 +82,7 @@ __always_inline static void submit_mode_event(struct metrics_by_hook_t* m, event->chmod.new = mode; event->chmod.old = old_mode; - __submit_event(event, m, FILE_ACTIVITY_CHMOD, filename, inode, use_bpf_d_path); + __submit_event(event, m, FILE_ACTIVITY_CHMOD, filename, inode, path_hooks_support_bpf_d_path); } __always_inline static void submit_ownership_event(struct metrics_by_hook_t* m, @@ -80,8 +91,7 @@ __always_inline static void submit_ownership_event(struct metrics_by_hook_t* m, unsigned long long uid, unsigned long long gid, unsigned long long old_uid, - unsigned long long old_gid, - bool use_bpf_d_path) { + unsigned long long old_gid) { struct event_t* event = bpf_ringbuf_reserve(&rb, sizeof(struct event_t), 0); if (event == NULL) { m->ringbuffer_full++; @@ -93,15 +103,14 @@ __always_inline static void submit_ownership_event(struct metrics_by_hook_t* m, event->chown.old.uid = old_uid; event->chown.old.gid = old_gid; - __submit_event(event, m, FILE_ACTIVITY_CHOWN, filename, inode, use_bpf_d_path); + __submit_event(event, m, FILE_ACTIVITY_CHOWN, filename, inode, path_hooks_support_bpf_d_path); } __always_inline static void submit_rename_event(struct metrics_by_hook_t* m, const char new_filename[PATH_MAX], const char old_filename[PATH_MAX], inode_key_t* new_inode, - inode_key_t* old_inode, - bool use_bpf_d_path) { + inode_key_t* old_inode) { struct event_t* event = bpf_ringbuf_reserve(&rb, sizeof(struct event_t), 0); if (event == NULL) { m->ringbuffer_full++; @@ -111,5 +120,5 @@ __always_inline static void submit_rename_event(struct metrics_by_hook_t* m, bpf_probe_read_str(event->rename.old_filename, PATH_MAX, old_filename); inode_copy_or_reset(&event->rename.old_inode, old_inode); - __submit_event(event, m, FILE_ACTIVITY_RENAME, new_filename, new_inode, use_bpf_d_path); + __submit_event(event, m, FILE_ACTIVITY_RENAME, new_filename, new_inode, path_hooks_support_bpf_d_path); } diff --git a/fact-ebpf/src/bpf/main.c b/fact-ebpf/src/bpf/main.c index 39a0622..3c71fd7 100644 --- a/fact-ebpf/src/bpf/main.c +++ b/fact-ebpf/src/bpf/main.c @@ -37,7 +37,7 @@ int BPF_PROG(trace_file_open, struct file* file) { goto ignored; } - struct bound_path_t* path = path_read(&file->f_path); + struct bound_path_t* path = path_read_unchecked(&file->f_path); if (path == NULL) { bpf_printk("Failed to read path"); m->file_open.error++; @@ -56,7 +56,7 @@ int BPF_PROG(trace_file_open, struct file* file) { break; } - submit_event(&m->file_open, event_type, path->path, &inode_key, true); + submit_open_event(&m->file_open, event_type, path->path, &inode_key); return 0; @@ -97,11 +97,9 @@ int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) { break; } - submit_event(&m->path_unlink, - FILE_ACTIVITY_UNLINK, - path->path, - &inode_key, - path_hooks_support_bpf_d_path); + submit_unlink_event(&m->path_unlink, + path->path, + &inode_key); return 0; } @@ -114,13 +112,7 @@ int BPF_PROG(trace_path_chmod, struct path* path, umode_t mode) { m->path_chmod.total++; - struct bound_path_t* bound_path = NULL; - if (path_hooks_support_bpf_d_path) { - bound_path = path_read(path); - } else { - bound_path = path_read_no_d_path(path); - } - + struct bound_path_t* bound_path = path_read(path); if (bound_path == NULL) { bpf_printk("Failed to read path"); m->path_chmod.error++; @@ -147,8 +139,7 @@ int BPF_PROG(trace_path_chmod, struct path* path, umode_t mode) { bound_path->path, &inode_key, mode, - old_mode, - path_hooks_support_bpf_d_path); + old_mode); return 0; } @@ -165,13 +156,7 @@ int BPF_PROG(trace_path_chown, struct path* path, unsigned long long uid, unsign m->path_chown.total++; - struct bound_path_t* bound_path = NULL; - if (path_hooks_support_bpf_d_path) { - bound_path = path_read(path); - } else { - bound_path = path_read_no_d_path(path); - } - + struct bound_path_t* bound_path = path_read(path); if (bound_path == NULL) { bpf_printk("Failed to read path"); m->path_chown.error++; @@ -203,8 +188,7 @@ int BPF_PROG(trace_path_chown, struct path* path, unsigned long long uid, unsign uid, gid, old_uid, - old_gid, - path_hooks_support_bpf_d_path); + old_gid); return 0; } @@ -249,8 +233,7 @@ int BPF_PROG(trace_path_rename, struct path* old_dir, new_path->path, old_path->path, &old_inode, - &new_inode, - path_hooks_support_bpf_d_path); + &new_inode); return 0; error: diff --git a/fact-ebpf/src/bpf/maps.h b/fact-ebpf/src/bpf/maps.h index 13f5fa5..048e393 100644 --- a/fact-ebpf/src/bpf/maps.h +++ b/fact-ebpf/src/bpf/maps.h @@ -116,6 +116,5 @@ __always_inline static struct metrics_t* get_metrics() { } uint64_t host_mount_ns; -volatile const bool path_hooks_support_bpf_d_path; // clang-format on