Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions fact-ebpf/src/bpf/inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#include <bpf/bpf_helpers.h>
// clang-format on

// From: man(2) statfs
#define BTRFS_SUPER_MAGIC 0x9123683E
#define OVERLAYFS_SUPER_MAGIC 0x794c7630
Comment thread
JoukoVirtanen marked this conversation as resolved.

/**
* Retrieve the inode and device numbers and return them as a new key.
Expand Down Expand Up @@ -58,6 +60,21 @@ __always_inline static inode_key_t inode_to_key(struct inode* inode) {
return key;
}

/**
* Check if the given inode belongs to an overlayfs filesystem.
*
* Overlayfs triggers LSM hooks for both the merged view and the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update.

* underlying filesystem. This can be used to distinguish between
* them.
*/
__always_inline static bool inode_is_overlayfs(struct inode* inode) {
if (inode == NULL) {
return false;
}
unsigned long magic = BPF_CORE_READ(inode, i_sb, s_magic);
return magic == OVERLAYFS_SUPER_MAGIC;
}

__always_inline static inode_value_t* inode_get(const struct inode_key_t* inode) {
if (inode == NULL) {
return NULL;
Expand Down
16 changes: 16 additions & 0 deletions fact-ebpf/src/bpf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,22 @@ int BPF_PROG(trace_file_open, struct file* file) {
goto ignored;
}

// Overlayfs deduplication: overlayfs triggers file_open twice — once
// on the overlay inode (with richer semantics like FMODE_CREATED) and
// once on the underlying filesystem inode. We keep the overlayfs
// event and skip the underlying duplicate.
__u64 pid_tgid = bpf_get_current_pid_tgid();
if (inode_is_overlayfs(file->f_inode)) {
char flag = 1;
bpf_map_update_elem(&overlayfs_dedup, &pid_tgid, &flag, BPF_ANY);
} else {
char* flag = bpf_map_lookup_elem(&overlayfs_dedup, &pid_tgid);
if (flag != NULL) {
bpf_map_delete_elem(&overlayfs_dedup, &pid_tgid);
goto ignored;
}
}

struct bound_path_t* path = path_read_unchecked(&file->f_path);
if (path == NULL) {
bpf_printk("Failed to read path");
Expand Down
9 changes: 9 additions & 0 deletions fact-ebpf/src/bpf/maps.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ struct {
__uint(max_entries, 1);
} metrics SEC(".maps");

// Track pid_tgid of overlayfs file_open events so we can skip the
// duplicate underlying filesystem event that follows immediately.
struct {
__uint(type, BPF_MAP_TYPE_LRU_PERCPU_HASH);
__type(key, __u64);
__type(value, char);
__uint(max_entries, 1);
} overlayfs_dedup SEC(".maps");

__always_inline static struct metrics_t* get_metrics() {
unsigned int zero = 0;
return bpf_map_lookup_elem(&metrics, &zero);
Expand Down
8 changes: 0 additions & 8 deletions tests/test_editors/test_nvim.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ def test_new_file_ovfs(editor_container, server):
events = [
Event(process=process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=fut, host_path=''),
]

server.wait_events(events, strict=True)
Expand Down Expand Up @@ -120,12 +118,8 @@ def test_open_file_ovfs(editor_container, server):
events = [
Event(process=touch, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=touch, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=nvim, event_type=EventType.CREATION,
file=vi_test_file, host_path=''),
Event(process=nvim, event_type=EventType.OPEN,
file=vi_test_file, host_path=''),
Event(process=nvim, event_type=EventType.OWNERSHIP,
file=vi_test_file, host_path='', owner_uid=0, owner_gid=0),
Event(process=nvim, event_type=EventType.UNLINK,
Expand All @@ -134,8 +128,6 @@ def test_open_file_ovfs(editor_container, server):
file=fut_backup, host_path='', old_file=fut, old_host_path=''),
Event(process=nvim, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=nvim, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=nvim, event_type=EventType.PERMISSION,
file=fut, host_path='', mode=0o100644),
Event(process=nvim, event_type=EventType.UNLINK,
Expand Down
4 changes: 0 additions & 4 deletions tests/test_editors/test_sed.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,8 @@ def test_sed_ovfs(vi_container, server):
events = [
Event(process=shell, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=shell, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=sed, event_type=EventType.CREATION,
file=sed_tmp_file, host_path=''),
Event(process=sed, event_type=EventType.OPEN,
file=sed_tmp_file, host_path=''),
Event(process=sed, event_type=EventType.OWNERSHIP,
file=sed_tmp_file, host_path='', owner_uid=0, owner_gid=0),
Event(process=sed, event_type=EventType.RENAME,
Expand Down
20 changes: 0 additions & 20 deletions tests/test_editors/test_vi.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,16 @@ def test_new_file_ovfs(vi_container, server):
events = [
Event(process=process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.CREATION,
file=swx_file, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=swx_file, host_path=''),
Event(process=process, event_type=EventType.UNLINK,
file=swx_file, host_path=''),
Event(process=process, event_type=EventType.UNLINK,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=process, event_type=EventType.UNLINK,
file=swap_file, host_path=''),
]
Expand Down Expand Up @@ -179,30 +171,20 @@ def test_open_file_ovfs(vi_container, server):
events = [
Event(process=touch_process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=touch_process, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=swx_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=swx_file, host_path=''),
Event(process=vi_process, event_type=EventType.UNLINK,
file=swx_file, host_path=''),
Event(process=vi_process, event_type=EventType.UNLINK,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.PERMISSION,
file=swap_file, host_path='', mode=0o644),
Event(process=vi_process, event_type=EventType.CREATION,
file=vi_test_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=vi_test_file, host_path=''),
Event(process=vi_process, event_type=EventType.OWNERSHIP,
file=vi_test_file, host_path='', owner_uid=0, owner_gid=0),
Event(process=vi_process, event_type=EventType.UNLINK,
Expand All @@ -211,8 +193,6 @@ def test_open_file_ovfs(vi_container, server):
file=fut_backup, host_path='', old_file=fut, old_host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=vi_process, event_type=EventType.PERMISSION,
file=fut, host_path='', mode=0o100644),
Event(process=vi_process, event_type=EventType.UNLINK,
Expand Down
20 changes: 0 additions & 20 deletions tests/test_editors/test_vim.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,16 @@ def test_new_file_ovfs(editor_container, server):
events = [
Event(process=process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.CREATION,
file=swx_file, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=swx_file, host_path=''),
Event(process=process, event_type=EventType.UNLINK,
file=swx_file, host_path=''),
Event(process=process, event_type=EventType.UNLINK,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=process, event_type=EventType.UNLINK,
file=swap_file, host_path=''),
]
Expand Down Expand Up @@ -173,30 +165,20 @@ def test_open_file_ovfs(editor_container, server):
events = [
Event(process=touch_process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=touch_process, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=swx_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=swx_file, host_path=''),
Event(process=vi_process, event_type=EventType.UNLINK,
file=swx_file, host_path=''),
Event(process=vi_process, event_type=EventType.UNLINK,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=swap_file, host_path=''),
Event(process=vi_process, event_type=EventType.PERMISSION,
file=swap_file, host_path='', mode=0o644),
Event(process=vi_process, event_type=EventType.CREATION,
file=vi_test_file, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=vi_test_file, host_path=''),
Event(process=vi_process, event_type=EventType.OWNERSHIP,
file=vi_test_file, host_path='', owner_uid=0, owner_gid=0),
Event(process=vi_process, event_type=EventType.UNLINK,
Expand All @@ -205,8 +187,6 @@ def test_open_file_ovfs(editor_container, server):
file=fut_backup, host_path='', old_file=fut, old_host_path=''),
Event(process=vi_process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=vi_process, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=vi_process, event_type=EventType.PERMISSION,
file=fut, host_path='', mode=0o100644),
Event(process=vi_process, event_type=EventType.UNLINK,
Expand Down
2 changes: 0 additions & 2 deletions tests/test_file_open.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,6 @@ def test_overlay(test_container, server):
events = [
Event(process=process, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=process, event_type=EventType.OPEN,
file=fut, host_path='')
]

server.wait_events(events)
Expand Down
2 changes: 0 additions & 2 deletions tests/test_path_chmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,6 @@ def test_overlay(test_container, server):
events = [
Event(process=touch, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=touch, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=chmod, event_type=EventType.PERMISSION,
file=fut, host_path='', mode=int(mode, 8)),
]
Expand Down
8 changes: 0 additions & 8 deletions tests/test_path_chown.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ def test_chown(test_container, server, filename):
events = [
Event(process=touch, event_type=EventType.CREATION, file=fut,
host_path=''),
Event(process=touch, event_type=EventType.OPEN, file=fut,
host_path=''),
Event(process=chown, event_type=EventType.OWNERSHIP, file=fut,
host_path='', owner_uid=TEST_UID, owner_gid=TEST_GID),
]
Expand Down Expand Up @@ -104,8 +102,6 @@ def test_multiple(test_container, server):
events.extend([
Event(process=touch, event_type=EventType.CREATION, file=fut,
host_path=''),
Event(process=touch, event_type=EventType.OPEN, file=fut,
host_path=''),
Event(process=chown, event_type=EventType.OWNERSHIP, file=fut,
host_path='', owner_uid=TEST_UID, owner_gid=TEST_GID),
])
Expand Down Expand Up @@ -150,8 +146,6 @@ def test_ignored(test_container, server):
events = [
Event(process=reported_touch, event_type=EventType.CREATION,
file=monitored_file, host_path=''),
Event(process=reported_touch, event_type=EventType.OPEN,
file=monitored_file, host_path=''),
Event(process=reported_chown, event_type=EventType.OWNERSHIP,
file=monitored_file, host_path='', owner_uid=TEST_UID, owner_gid=TEST_GID),
]
Expand Down Expand Up @@ -201,8 +195,6 @@ def test_no_change(test_container, server):
events = [
Event(process=touch, event_type=EventType.CREATION, file=fut,
host_path=''),
Event(process=touch, event_type=EventType.OPEN, file=fut,
host_path=''),
chown_event,
chown_event,
]
Expand Down
2 changes: 0 additions & 2 deletions tests/test_path_rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ def test_overlay(test_container, server):
events = [
Event(process=touch, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=touch, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=mv, event_type=EventType.RENAME,
file=new_fut, host_path='', old_file=fut, old_host_path=''),
]
Expand Down
2 changes: 0 additions & 2 deletions tests/test_path_unlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ def test_overlay(test_container, server):
events = [
Event(process=touch, event_type=EventType.CREATION,
file=fut, host_path=''),
Event(process=touch, event_type=EventType.OPEN,
file=fut, host_path=''),
Event(process=rm, event_type=EventType.UNLINK,
file=fut, host_path=''),
]
Expand Down
Loading