diff --git a/Cargo.lock b/Cargo.lock index 0659775d..b9400130 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,8 +148,7 @@ dependencies = [ [[package]] name = "aya" version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66e644424fada9fff4fdc63848db1732fb69b626e8328202ef55c03df1f4d939" +source = "git+https://github.com/aya-rs/aya.git?rev=c29cd71cb4fe1440bc0d566633afa822f1b41fc5#c29cd71cb4fe1440bc0d566633afa822f1b41fc5" dependencies = [ "assert_matches", "aya-obj", @@ -166,8 +165,7 @@ dependencies = [ [[package]] name = "aya-obj" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c76b9c75d9cdc155ff8f6a06d61e873f67bf47be8cfa92a3b5aaea43f4b4077" +source = "git+https://github.com/aya-rs/aya.git?rev=c29cd71cb4fe1440bc0d566633afa822f1b41fc5#c29cd71cb4fe1440bc0d566633afa822f1b41fc5" dependencies = [ "bytes", "log", diff --git a/Cargo.toml b/Cargo.toml index f59a4de9..27a4bf87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] } diff --git a/fact-ebpf/src/bpf/main.c b/fact-ebpf/src/bpf/main.c index 94471cdd..3477ebcc 100644 --- a/fact-ebpf/src/bpf/main.c +++ b/fact-ebpf/src/bpf/main.c @@ -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; @@ -78,7 +115,6 @@ int BPF_PROG(trace_file_open, struct file* file) { } submit_open_event(&args, event_type); - return 0; ignored: @@ -86,8 +122,7 @@ int BPF_PROG(trace_file_open, struct file* file) { 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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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: @@ -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; @@ -415,9 +442,8 @@ __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; @@ -425,9 +451,8 @@ int BPF_PROG(trace_inode_setxattr, struct mnt_idmap* idmap, struct dentry* dentr 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; @@ -435,9 +460,8 @@ int BPF_PROG(trace_inode_removexattr, struct mnt_idmap* idmap, struct dentry* de 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; @@ -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; @@ -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; @@ -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; @@ -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; @@ -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; diff --git a/fact/src/bpf/mod.rs b/fact/src/bpf/mod.rs index 1eb58add..dc422edd 100644 --- a/fact/src/bpf/mod.rs +++ b/fact/src/bpf/mod.rs @@ -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()?; diff --git a/fact/src/host_scanner.rs b/fact/src/host_scanner.rs index 1ea00a5d..3e8a808c 100644 --- a/fact/src/host_scanner.rs +++ b/fact/src/host_scanner.rs @@ -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 =>