Skip to content

Commit 08e05bd

Browse files
committed
feat: use BPF_MAP_TYPE_INODE_STORAGE for ignored cache
Whenever we find a file that we should ignore based on its path, we can attach a byte to its inode so that we will know on future accesses that the file should be ignored before we do any sort of processing on our hooks. Because the information is attached to the inode itself, when the inode is removed, the storage will be cleaned up on its own. A re-used pointer to an inode should also not cause false hits, since this is specific to the inode we attached to and should go away when the inode is freed.
1 parent 54874a6 commit 08e05bd

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

fact-ebpf/src/bpf/main.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ int BPF_PROG(trace_file_open, struct file* file) {
3434
goto ignored;
3535
}
3636

37+
if (is_ignored(file->f_path.dentry->d_inode)) {
38+
goto ignored;
39+
}
40+
3741
struct bound_path_t* path = path_read(&file->f_path);
3842
if (path == NULL) {
3943
bpf_printk("Failed to read path");
@@ -42,6 +46,7 @@ int BPF_PROG(trace_file_open, struct file* file) {
4246
}
4347

4448
if (!is_monitored(path)) {
49+
add_ignored(file->f_path.dentry->d_inode);
4550
goto ignored;
4651
}
4752

@@ -61,6 +66,10 @@ int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {
6166

6267
m->path_unlink.total++;
6368

69+
if (is_ignored(dentry->d_inode)) {
70+
goto ignored;
71+
}
72+
6473
struct bound_path_t* path = path_read(dir);
6574
if (path == NULL) {
6675
bpf_printk("Failed to read path");
@@ -80,8 +89,7 @@ int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {
8089
}
8190

8291
if (!is_monitored(path)) {
83-
m->path_unlink.ignored++;
84-
return 0;
92+
goto ignored;
8593
}
8694

8795
submit_event(&m->path_unlink, FILE_ACTIVITY_UNLINK, path->path, dentry);
@@ -90,4 +98,8 @@ int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {
9098
error:
9199
m->path_unlink.error++;
92100
return 0;
101+
102+
ignored:
103+
m->path_unlink.ignored++;
104+
return 0;
93105
}

fact-ebpf/src/bpf/maps.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,20 @@ __always_inline static struct metrics_t* get_metrics() {
8585

8686
uint64_t host_mount_ns;
8787

88+
struct {
89+
__uint(type, BPF_MAP_TYPE_INODE_STORAGE);
90+
__type(key, unsigned int);
91+
__type(value, char);
92+
__uint(max_entries, 0);
93+
__uint(map_flags, BPF_F_NO_PREALLOC);
94+
} ignored SEC(".maps");
95+
96+
__always_inline static void add_ignored(struct inode* inode) {
97+
bpf_inode_storage_get(&ignored, inode, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE);
98+
}
99+
100+
__always_inline static bool is_ignored(struct inode* inode) {
101+
return bpf_inode_storage_get(&ignored, inode, NULL, 0) != NULL;
102+
}
103+
88104
// clang-format on

fact/src/bpf.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ impl Bpf {
4242
)
4343
.set_global("host_mount_ns", &host_info::get_host_mount_ns(), true)
4444
.set_max_entries(RINGBUFFER_NAME, config.ringbuf_size() * 1024)
45+
.allow_unsupported_maps()
4546
.load(fact_ebpf::EBPF_OBJ)?;
4647

4748
let ringbuf = match obj.take_map(RINGBUFFER_NAME) {

0 commit comments

Comments
 (0)