Skip to content

Commit fc3ae8f

Browse files
committed
feat: use bpf_path_d_path for reading paths
This is a safer alternative to the bpf_d_path helper that enforces the use of KF_TRUSTED_ARGS semantics, meaning we need to use proper RCU and refcounting to prevent the underlying memory being walked from disappearing from underneath our feet.
1 parent 61cebd7 commit fc3ae8f

3 files changed

Lines changed: 38 additions & 9 deletions

File tree

fact-ebpf/src/bpf/d_path.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ __always_inline static long __d_path(const struct path* path, char* buf, int buf
141141
}
142142

143143
__always_inline static long d_path(struct path* path, char* buf, int buflen, bool use_bpf_helper) {
144-
if (use_bpf_helper) {
144+
if (bpf_ksym_exists(bpf_path_d_path)) {
145+
return bpf_path_d_path(path, buf, buflen);
146+
} else if (use_bpf_helper) {
145147
return bpf_d_path(path, buf, buflen);
146148
}
147149
return __d_path(path, buf, buflen);

fact-ebpf/src/bpf/main.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// clang-format off
2+
#include "d_path.h"
23
#include "vmlinux.h"
34

45
#include "file.h"
@@ -552,9 +553,16 @@ FACT_BPF_PROG2(sb_umount, struct vfsmount*, mnt, int, flags) {
552553
struct submit_event_args_t args = {.metrics = &m->sb_umount};
553554
args.metrics->total++;
554555

555-
struct path p = {.dentry = BPF_CORE_READ(mnt, mnt_root), .mnt = mnt};
556-
struct bound_path_t* bound_path = _path_read(&p, BOUND_PATH_MAIN, false);
556+
// TODO: Figure out a better way to read the path with bpf_path_d_path.
557+
struct bound_path_t* bound_path = get_bound_path(BOUND_PATH_MAIN);
557558
if (bound_path == NULL) {
559+
bpf_printk("Failed to get bound_path buffer");
560+
args.metrics->error++;
561+
return 0;
562+
}
563+
564+
struct path p = {.dentry = BPF_CORE_READ(mnt, mnt_root), .mnt = mnt};
565+
if (__d_path(&p, bound_path->path, PATH_MAX) <= 0) {
558566
bpf_printk("Failed to read umount directory");
559567
args.metrics->error++;
560568
return 0;

fact-ebpf/src/bpf/process.h

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,37 @@ __always_inline static const char* get_memory_cgroup(struct helper_t* helper) {
7878
}
7979

8080
__always_inline static void process_fill_lineage(process_t* p, struct helper_t* helper, bool use_bpf_d_path) {
81-
struct task_struct* task = (struct task_struct*)bpf_get_current_task_btf();
81+
struct task_struct* task = bpf_task_acquire(bpf_get_current_task_btf());
82+
if (task == NULL) {
83+
return;
84+
}
8285
p->lineage_len = 0;
8386

87+
bpf_rcu_read_lock();
8488
for (int i = 0; i < LINEAGE_MAX; i++) {
85-
struct task_struct* parent = task->real_parent;
89+
struct task_struct* parent = bpf_task_acquire(task->real_parent);
8690

87-
if (task == parent || parent->pid == 0) {
88-
return;
91+
if (parent == NULL) {
92+
break;
93+
} else if (task == parent || parent->pid == 0) {
94+
bpf_task_release(parent);
95+
break;
8996
}
97+
98+
bpf_task_release(task);
9099
task = parent;
91100

92101
p->lineage[i].uid = task->cred->uid.val;
93102

94-
d_path(&task->mm->exe_file->f_path, p->lineage[i].exe_path, PATH_MAX, use_bpf_d_path);
103+
struct file* exe_file = bpf_get_task_exe_file(task);
104+
if (exe_file != NULL) {
105+
d_path(&exe_file->f_path, p->lineage[i].exe_path, PATH_MAX, use_bpf_d_path);
106+
bpf_put_file(exe_file);
107+
}
95108
p->lineage_len++;
96109
}
110+
bpf_rcu_read_unlock();
111+
bpf_task_release(task);
97112
}
98113

99114
__always_inline static unsigned long get_mount_ns() {
@@ -131,7 +146,11 @@ __always_inline static int64_t process_fill(process_t* p, bool use_bpf_d_path) {
131146
return -1;
132147
}
133148

134-
d_path(&task->mm->exe_file->f_path, p->exe_path, PATH_MAX, use_bpf_d_path);
149+
struct file* exe_file = bpf_get_task_exe_file(task);
150+
if (exe_file != NULL) {
151+
d_path(&exe_file->f_path, p->exe_path, PATH_MAX, use_bpf_d_path);
152+
bpf_put_file(exe_file);
153+
}
135154

136155
const char* cg = get_memory_cgroup(helper);
137156
if (cg != NULL) {

0 commit comments

Comments
 (0)