diff --git a/fact-ebpf/src/bpf/events.h b/fact-ebpf/src/bpf/events.h index 3839513..bdb801b 100644 --- a/fact-ebpf/src/bpf/events.h +++ b/fact-ebpf/src/bpf/events.h @@ -1,6 +1,7 @@ #include #include "maps.h" +#include "metadata.h" #include "process.h" #include "types.h" #include "vmlinux.h" @@ -28,6 +29,11 @@ __always_inline static void submit_event(struct metrics_by_hook_t* m, file_activ goto error; } + err = metadata_fill(&event->metadata, dentry); + if (err) { + bpf_printk("Failed to fill file metadata: %d", err); + } + m->added++; bpf_ringbuf_submit(event, 0); return; diff --git a/fact-ebpf/src/bpf/metadata.h b/fact-ebpf/src/bpf/metadata.h new file mode 100644 index 0000000..e412633 --- /dev/null +++ b/fact-ebpf/src/bpf/metadata.h @@ -0,0 +1,24 @@ +#pragma once + +// clang-format off +#include "vmlinux.h" + +#include "types.h" + +#include +#include +// clang-format on + +static __always_inline uint64_t metadata_fill(metadata_t* metadata, struct dentry* dentry) { + struct inode* inode = BPF_CORE_READ(dentry, d_inode); + if (inode == NULL) { + return -1; + } + + metadata->mode = BPF_CORE_READ(inode, i_mode); + metadata->uid = BPF_CORE_READ(inode, i_uid.val); + metadata->gid = BPF_CORE_READ(inode, i_gid.val); + metadata->size = BPF_CORE_READ(inode, i_size); + + return 0; +} diff --git a/fact-ebpf/src/bpf/types.h b/fact-ebpf/src/bpf/types.h index f32ade1..379ac1d 100644 --- a/fact-ebpf/src/bpf/types.h +++ b/fact-ebpf/src/bpf/types.h @@ -32,6 +32,13 @@ typedef struct process_t { char in_root_mount_ns; } process_t; +typedef struct metadata_t { + short unsigned int mode; + unsigned int uid; + unsigned int gid; + long long int size; +} metadata_t; + typedef enum file_activity_type_t { FILE_ACTIVITY_INIT = -1, FILE_ACTIVITY_OPEN = 0, @@ -44,6 +51,7 @@ struct event_t { process_t process; char filename[PATH_MAX]; char host_file[PATH_MAX]; + metadata_t metadata; file_activity_type_t type; }; diff --git a/fact/src/event/mod.rs b/fact/src/event/mod.rs index 745b426..e4756dc 100644 --- a/fact/src/event/mod.rs +++ b/fact/src/event/mod.rs @@ -4,7 +4,7 @@ use std::{ffi::CStr, os::raw::c_char, path::PathBuf}; use serde::Serialize; -use fact_ebpf::{event_t, file_activity_type_t, PATH_MAX}; +use fact_ebpf::{event_t, file_activity_type_t, metadata_t, PATH_MAX}; use crate::host_info; use process::Process; @@ -27,6 +27,7 @@ pub struct Event { hostname: &'static str, process: Process, file: FileData, + metadata: Metadata, } impl Event { @@ -52,12 +53,14 @@ impl Event { file_activity_type_t::FILE_ACTIVITY_UNLINK => FileData::Unlink(inner), invalid => unreachable!("Invalid event type: {invalid:?}"), }; + let metadata = Metadata::default(); Ok(Event { timestamp, hostname, process, file, + metadata, }) } } @@ -69,12 +72,14 @@ impl TryFrom<&event_t> for Event { let process = Process::try_from(value.process)?; let timestamp = host_info::get_boot_time() + value.timestamp; let file = FileData::new(value.type_, value.filename, value.host_file)?; + let metadata = Metadata::from(value.metadata); Ok(Event { timestamp, hostname: host_info::get_hostname(), process, file, + metadata, }) } } @@ -195,3 +200,28 @@ impl From for fact_api::FileActivityBase { } } } + +#[derive(Debug, Clone, Serialize, Default)] +struct Metadata { + mode: u16, + uid: u32, + gid: u32, + size: i64, +} + +impl From for Metadata { + fn from(value: metadata_t) -> Self { + let metadata_t { + mode, + uid, + gid, + size, + } = value; + Metadata { + mode, + uid, + gid, + size, + } + } +}