diff --git a/fact-ebpf/src/bpf/d_path.h b/fact-ebpf/src/bpf/d_path.h index a922600e..f563215d 100644 --- a/fact-ebpf/src/bpf/d_path.h +++ b/fact-ebpf/src/bpf/d_path.h @@ -141,7 +141,9 @@ __always_inline static long __d_path(const struct path* path, char* buf, int buf } __always_inline static long d_path(struct path* path, char* buf, int buflen, bool use_bpf_helper) { - if (use_bpf_helper) { + if (bpf_ksym_exists(bpf_path_d_path)) { + return bpf_path_d_path(path, buf, buflen); + } else if (use_bpf_helper) { return bpf_d_path(path, buf, buflen); } return __d_path(path, buf, buflen); diff --git a/fact-ebpf/src/bpf/main.c b/fact-ebpf/src/bpf/main.c index 3477ebcc..77cd50e7 100644 --- a/fact-ebpf/src/bpf/main.c +++ b/fact-ebpf/src/bpf/main.c @@ -1,4 +1,5 @@ // clang-format off +#include "d_path.h" #include "vmlinux.h" #include "file.h" @@ -552,9 +553,16 @@ FACT_BPF_PROG2(sb_umount, struct vfsmount*, mnt, int, flags) { struct submit_event_args_t args = {.metrics = &m->sb_umount}; args.metrics->total++; - struct path p = {.dentry = BPF_CORE_READ(mnt, mnt_root), .mnt = mnt}; - struct bound_path_t* bound_path = _path_read(&p, BOUND_PATH_MAIN, false); + // TODO: Figure out a better way to read the path with bpf_path_d_path. + struct bound_path_t* bound_path = get_bound_path(BOUND_PATH_MAIN); if (bound_path == NULL) { + bpf_printk("Failed to get bound_path buffer"); + args.metrics->error++; + return 0; + } + + struct path p = {.dentry = BPF_CORE_READ(mnt, mnt_root), .mnt = mnt}; + if (__d_path(&p, bound_path->path, PATH_MAX) <= 0) { bpf_printk("Failed to read umount directory"); args.metrics->error++; return 0; diff --git a/fact-ebpf/src/bpf/process.h b/fact-ebpf/src/bpf/process.h index 5061ee38..dcd04992 100644 --- a/fact-ebpf/src/bpf/process.h +++ b/fact-ebpf/src/bpf/process.h @@ -77,23 +77,49 @@ __always_inline static const char* get_memory_cgroup(struct helper_t* helper) { return helper->buf; } +__always_inline static long read_exe_file(struct task_struct* task, char buf[PATH_MAX], bool use_bpf_d_path) { + if (bpf_ksym_exists(bpf_get_task_exe_file)) { + long res = -1; + struct file* exe_file = bpf_get_task_exe_file(task); + if (exe_file != NULL) { + res = d_path(&exe_file->f_path, buf, PATH_MAX, use_bpf_d_path); + bpf_put_file(exe_file); + } + return res; + } else if (use_bpf_d_path) { + return bpf_d_path(&task->mm->exe_file->f_path, buf, PATH_MAX); + } else { + return __d_path(&task->mm->exe_file->f_path, buf, PATH_MAX); + } +} + __always_inline static void process_fill_lineage(process_t* p, struct helper_t* helper, bool use_bpf_d_path) { - struct task_struct* task = (struct task_struct*)bpf_get_current_task_btf(); + struct task_struct* task = bpf_task_acquire(bpf_get_current_task_btf()); + if (task == NULL) { + return; + } p->lineage_len = 0; for (int i = 0; i < LINEAGE_MAX; i++) { - struct task_struct* parent = task->real_parent; + bpf_rcu_read_lock(); + struct task_struct* parent = bpf_task_acquire(task->real_parent); + bpf_rcu_read_unlock(); - if (task == parent || parent->pid == 0) { - return; + if (parent == NULL) { + break; + } else if (task == parent || parent->pid == 0) { + bpf_task_release(parent); + break; } + + bpf_task_release(task); task = parent; p->lineage[i].uid = task->cred->uid.val; - - d_path(&task->mm->exe_file->f_path, p->lineage[i].exe_path, PATH_MAX, use_bpf_d_path); + read_exe_file(task, p->lineage[i].exe_path, use_bpf_d_path); p->lineage_len++; } + bpf_task_release(task); } __always_inline static unsigned long get_mount_ns() { @@ -131,7 +157,7 @@ __always_inline static int64_t process_fill(process_t* p, bool use_bpf_d_path) { return -1; } - d_path(&task->mm->exe_file->f_path, p->exe_path, PATH_MAX, use_bpf_d_path); + read_exe_file(task, p->exe_path, use_bpf_d_path); const char* cg = get_memory_cgroup(helper); if (cg != NULL) {