diff --git a/Cargo.lock b/Cargo.lock index 63e36a26..7b32f398 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 f59198bb..617b4174 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ license = "MIT OR Apache-2.0" [workspace.dependencies] anyhow = { version = "1", default-features = false, features = ["std", "backtrace"] } -aya = { version = "0.14.0", default-features = false } +aya = { git = "https://github.com/aya-rs/aya.git", rev = "c29cd71cb4fe1440bc0d566633afa822f1b41fc5", default-features = false } libc = { version = "0.2.159", default-features = false } prost = "0.14.0" prost-types = "0.14.0" diff --git a/fact-ebpf/src/bpf/main.c b/fact-ebpf/src/bpf/main.c index 8d5aae7d..cf372197 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_link") -int BPF_PROG(trace_path_link, struct dentry* old_dentry, const struct path* new_dir, struct dentry* new_dentry) { +FACT_BPF_PROG3(path_link, struct dentry*, old_dentry, const struct path*, new_dir, struct dentry*, new_dentry) { struct metrics_t* m = get_metrics(); if (m == NULL) { return 0; @@ -123,8 +158,7 @@ int BPF_PROG(trace_path_link, struct dentry* old_dentry, const struct path* new_ 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; @@ -158,8 +192,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; @@ -186,15 +219,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; @@ -224,14 +255,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; @@ -338,8 +367,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; @@ -368,7 +396,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: @@ -377,8 +404,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; @@ -462,9 +488,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; @@ -472,9 +497,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; @@ -482,9 +506,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; @@ -507,8 +530,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; @@ -536,8 +558,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; @@ -566,12 +587,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; @@ -601,12 +620,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; @@ -653,8 +670,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 10362574..41416785 100644 --- a/fact/src/bpf/mod.rs +++ b/fact/src/bpf/mod.rs @@ -194,7 +194,7 @@ impl Bpf { let mut new_paths = Vec::with_capacity(patterns.len()); for p in patterns.iter().map(|p| host_info::remove_host_mount(p)) { 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); } new_paths diff --git a/fact/src/host_scanner.rs b/fact/src/host_scanner.rs index 907c0a71..e2b0dcc7 100644 --- a/fact/src/host_scanner.rs +++ b/fact/src/host_scanner.rs @@ -352,7 +352,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 =>