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
6 changes: 2 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ default-members = ["fact"]
license = "MIT OR Apache-2.0"

[workspace.dependencies]
aya = { version = "0.14.0", default-features = false }
aya = { git = "https://github.com/aya-rs/aya.git", rev = "c29cd71cb4fe1440bc0d566633afa822f1b41fc5", default-features = false }

anyhow = { version = "1", default-features = false, features = ["std", "backtrace"] }
clap = { version = "4.5.41", features = ["derive", "env"] }
Expand Down
99 changes: 58 additions & 41 deletions fact-ebpf/src/bpf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,45 @@ char _license[] SEC("license") = "Dual MIT/GPL";
#define FMODE_PWRITE ((fmode_t)(1 << 4))
#define FMODE_CREATED ((fmode_t)(1 << 20))

SEC("lsm/file_open")
int BPF_PROG(trace_file_open, struct file* file) {
#define STRINGIFY(a) STR(a)
#define STR(a) #a

#define __MAP0(m, ...)
#define __MAP1(m, t, a, ...) m(t, a)
#define __MAP2(m, t, a, ...) m(t, a), __MAP1(m, __VA_ARGS__)
#define __MAP3(m, t, a, ...) m(t, a), __MAP2(m, __VA_ARGS__)
#define __MAP4(m, t, a, ...) m(t, a), __MAP3(m, __VA_ARGS__)
#define __MAP5(m, t, a, ...) m(t, a), __MAP4(m, __VA_ARGS__)
#define __MAP6(m, t, a, ...) m(t, a), __MAP5(m, __VA_ARGS__)
#define __MAP(n, ...) __MAP##n(__VA_ARGS__)

#define __CAT(t, a) t a
#define __ARG(t, a) a

#define FACT_BPF_PROG(hook, n, args...) \
static __always_inline int _handle_##hook(__MAP(n, __CAT, args)); \
SEC("lsm/" STRINGIFY(hook)) \
int BPF_PROG(trace_##hook, __MAP(n, __CAT, args)) { \
if (bpf_ksym_exists(bpf_preempt_disable)) { \
bpf_preempt_disable(); \
} \
int res = _handle_##hook(__MAP(n, __ARG, args)); \
\
if (bpf_ksym_exists(bpf_preempt_enable)) { \
bpf_preempt_enable(); \
} \
return res; \
} \
static __always_inline int _handle_##hook(__MAP(n, __CAT, args))

#define FACT_BPF_PROG1(hook, args...) FACT_BPF_PROG(hook, 1, args)
#define FACT_BPF_PROG2(hook, args...) FACT_BPF_PROG(hook, 2, args)
#define FACT_BPF_PROG3(hook, args...) FACT_BPF_PROG(hook, 3, args)
#define FACT_BPF_PROG4(hook, args...) FACT_BPF_PROG(hook, 4, args)
#define FACT_BPF_PROG5(hook, args...) FACT_BPF_PROG(hook, 5, args)
#define FACT_BPF_PROG6(hook, args...) FACT_BPF_PROG(hook, 6, args)

FACT_BPF_PROG1(file_open, struct file*, file) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -78,16 +115,14 @@ int BPF_PROG(trace_file_open, struct file* file) {
}

submit_open_event(&args, event_type);

return 0;

ignored:
m->file_open.ignored++;
return 0;
}

SEC("lsm/path_unlink")
int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {
FACT_BPF_PROG2(path_unlink, struct path*, dir, struct dentry*, dentry) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -119,8 +154,7 @@ int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {
return 0;
}

SEC("lsm/path_chmod")
int BPF_PROG(trace_path_chmod, struct path* path, umode_t mode) {
FACT_BPF_PROG2(path_chmod, struct path*, path, umode_t, mode) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand All @@ -147,15 +181,13 @@ int BPF_PROG(trace_path_chmod, struct path* path, umode_t mode) {

umode_t old_mode = BPF_CORE_READ(path, dentry, d_inode, i_mode);
submit_mode_event(&args, mode, old_mode);

return 0;
}

/* path_chown takes _unsigned long long_ for uid and gid because kuid_t and kgid_t (structs)
fit in registers and since they contain only one integer, their content is extended to the
size of the BPF registers (64 bits) to simplify further arithmetic operations. */
SEC("lsm/path_chown")
int BPF_PROG(trace_path_chown, struct path* path, unsigned long long uid, unsigned long long gid) {
FACT_BPF_PROG3(path_chown, struct path*, path, unsigned long long, uid, unsigned long long, gid) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -185,14 +217,12 @@ int BPF_PROG(trace_path_chown, struct path* path, unsigned long long uid, unsign
unsigned long long old_gid = BPF_CORE_READ(d, d_inode, i_gid.val);

submit_ownership_event(&args, uid, gid, old_uid, old_gid);

return 0;
}

SEC("lsm/path_rename")
int BPF_PROG(trace_path_rename, struct path* old_dir,
struct dentry* old_dentry, struct path* new_dir,
struct dentry* new_dentry, unsigned int flags) {
FACT_BPF_PROG5(path_rename, struct path*, old_dir,
struct dentry*, old_dentry, struct path*, new_dir,
struct dentry*, new_dentry, unsigned int, flags) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -291,8 +321,7 @@ int BPF_PROG(trace_path_rename, struct path* old_dir,
return 0;
}

SEC("lsm/path_mkdir")
int BPF_PROG(trace_path_mkdir, struct path* dir, struct dentry* dentry, umode_t mode) {
FACT_BPF_PROG3(path_mkdir, struct path*, dir, struct dentry*, dentry, umode_t, mode) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -321,7 +350,6 @@ int BPF_PROG(trace_path_mkdir, struct path* dir, struct dentry* dentry, umode_t
return 0;
}
mkdir_ctx->event_type = DIR_ACTIVITY_CREATION;

return 0;

error:
Expand All @@ -330,8 +358,7 @@ int BPF_PROG(trace_path_mkdir, struct path* dir, struct dentry* dentry, umode_t
return 0;
}

SEC("lsm/d_instantiate")
int BPF_PROG(trace_d_instantiate, struct dentry* dentry, struct inode* inode) {
FACT_BPF_PROG2(d_instantiate, struct dentry*, dentry, struct inode*, inode) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -415,29 +442,26 @@ __always_inline static int handle_xattr(struct metrics_by_hook_t* hook_metrics,
return 0;
}

SEC("lsm/inode_setxattr")
int BPF_PROG(trace_inode_setxattr, struct mnt_idmap* idmap, struct dentry* dentry,
const char* name, const void* value, size_t size, int flags) {
FACT_BPF_PROG6(inode_setxattr, struct mnt_idmap*, idmap, struct dentry*, dentry,
const char*, name, const void*, value, size_t, size, int, flags) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
}
return handle_xattr(&m->inode_setxattr, dentry, name, FILE_ACTIVITY_SETXATTR);
}

SEC("lsm/inode_removexattr")
int BPF_PROG(trace_inode_removexattr, struct mnt_idmap* idmap, struct dentry* dentry,
const char* name) {
FACT_BPF_PROG3(inode_removexattr, struct mnt_idmap*, idmap, struct dentry*, dentry,
const char*, name) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
}
return handle_xattr(&m->inode_removexattr, dentry, name, FILE_ACTIVITY_REMOVEXATTR);
}

SEC("lsm/inode_set_acl")
int BPF_PROG(trace_inode_set_acl, struct mnt_idmap* idmap, struct dentry* dentry,
const char* acl_name, struct posix_acl* kacl) {
FACT_BPF_PROG4(inode_set_acl, struct mnt_idmap*, idmap, struct dentry*, dentry,
const char*, acl_name, struct posix_acl*, kacl) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand All @@ -460,8 +484,7 @@ int BPF_PROG(trace_inode_set_acl, struct mnt_idmap* idmap, struct dentry* dentry
return 0;
}

SEC("lsm/path_rmdir")
int BPF_PROG(trace_path_rmdir, struct path* dir, struct dentry* dentry) {
FACT_BPF_PROG2(path_rmdir, struct path*, dir, struct dentry*, dentry) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -489,8 +512,7 @@ int BPF_PROG(trace_path_rmdir, struct path* dir, struct dentry* dentry) {
return 0;
}

SEC("lsm/sb_mount")
int BPF_PROG(trace_sb_mount, const char* dev_name, struct path* path, const char* type, unsigned long flags, void* data) {
FACT_BPF_PROG5(sb_mount, const char*, dev_name, struct path*, path, const char*, type, unsigned long, flags, void*, data) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -519,12 +541,10 @@ int BPF_PROG(trace_sb_mount, const char* dev_name, struct path* path, const char
}

submit_mount_event(&args);

return 0;
}

SEC("lsm/sb_umount")
int BPF_PROG(trace_sb_umount, struct vfsmount* mnt, int flags) {
FACT_BPF_PROG2(sb_umount, struct vfsmount*, mnt, int, flags) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -554,12 +574,10 @@ int BPF_PROG(trace_sb_umount, struct vfsmount* mnt, int flags) {
}

submit_umount_event(&args);

return 0;
}

SEC("lsm/move_mount")
int BPF_PROG(trace_move_mount, struct path* from, struct path* to) {
FACT_BPF_PROG2(move_mount, struct path*, from, struct path*, to) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down Expand Up @@ -606,8 +624,7 @@ int BPF_PROG(trace_move_mount, struct path* from, struct path* to) {
return 0;
}

SEC("lsm/path_symlink")
int BPF_PROG(trace_path_symlink, struct path* dir, struct dentry* dentry, const char* old_name) {
FACT_BPF_PROG3(path_symlink, struct path*, dir, struct dentry*, dentry, const char*, old_name) {
struct metrics_t* m = get_metrics();
if (m == NULL) {
return 0;
Expand Down
2 changes: 1 addition & 1 deletion fact/src/bpf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl Bpf {
);

let prefix = path_prefix_t::try_from(p)?;
self.paths_lpm_map.insert(&prefix.into(), 0, 0)?;
self.paths_lpm_map.insert(&prefix.into(), &0, 0)?;
new_paths.push(prefix);
}
self.paths_globset = builder.build()?;
Expand Down
2 changes: 1 addition & 1 deletion fact/src/host_scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ impl HostScanner {
}
};

match self.kernel_inode_map.borrow_mut().insert(inode, 0, 0) {
match self.kernel_inode_map.borrow_mut().insert(&inode, &0, 0) {
Ok(_) => Ok(()),
Err(MapError::SyscallError(SyscallError { io_error, .. }))
if io_error.kind() == io::ErrorKind::ArgumentListTooLong =>
Expand Down
Loading