Skip to content
Draft
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
1 change: 1 addition & 0 deletions fact-ebpf/src/bpf/bound_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ __always_inline static enum path_append_status_t path_append_dentry(struct bound

path->len += len;
path_write_char(path->path, path->len, '\0');
path->len++;

return 0;
}
2 changes: 1 addition & 1 deletion fact-ebpf/src/bpf/d_path.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ __always_inline static long __d_path(const struct path* path, char* buf, int buf
dentry = parent;
}

bpf_probe_read_str(buf, buflen, &helper->buf[offset]);
bpf_probe_read(buf, buflen - offset, &helper->buf[offset]);
return buflen - offset;
}

Expand Down
5 changes: 3 additions & 2 deletions fact-ebpf/src/bpf/events.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

__always_inline static void submit_event(struct metrics_by_hook_t* m,
file_activity_type_t event_type,
const char filename[PATH_MAX],
struct bound_path_t* path,
inode_key_t* inode,
bool use_bpf_d_path) {
struct event_t* event = bpf_ringbuf_reserve(&rb, sizeof(struct event_t), 0);
Expand All @@ -25,7 +25,8 @@ __always_inline static void submit_event(struct metrics_by_hook_t* m,
event->type = event_type;
event->timestamp = bpf_ktime_get_boot_ns();
inode_copy_or_reset(&event->inode, inode);
bpf_probe_read_str(event->filename, PATH_MAX, filename);
bpf_probe_read(event->filename, path->len & (PATH_MAX - 1), path->path);
event->filename_len = path->len;

struct helper_t* helper = get_helper();
if (helper == NULL) {
Expand Down
4 changes: 2 additions & 2 deletions fact-ebpf/src/bpf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ int BPF_PROG(trace_file_open, struct file* file) {
break;
}

submit_event(&m->file_open, event_type, path->path, &inode_key, true);
submit_event(&m->file_open, event_type, path, &inode_key, true);

return 0;

Expand Down Expand Up @@ -116,7 +116,7 @@ int BPF_PROG(trace_path_unlink, struct path* dir, struct dentry* dentry) {

submit_event(&m->path_unlink,
FILE_ACTIVITY_UNLINK,
path->path,
path,
&inode_key,
path_unlink_supports_bpf_d_path);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion fact-ebpf/src/bpf/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ __always_inline static int64_t process_fill(process_t* p, bool use_bpf_d_path) {
return -1;
}

d_path(&task->mm->exe_file->f_path, p->exe_path, PATH_MAX, use_bpf_d_path);
p->exe_path_len = d_path(&task->mm->exe_file->f_path, p->exe_path, PATH_MAX, use_bpf_d_path);

const char* cg = get_memory_cgroup(helper);
if (cg != NULL) {
Expand Down
2 changes: 2 additions & 0 deletions fact-ebpf/src/bpf/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef struct process_t {
char args[4096];
unsigned int args_len;
char exe_path[PATH_MAX];
short unsigned int exe_path_len;
char memory_cgroup[PATH_MAX];
unsigned int uid;
unsigned int gid;
Expand Down Expand Up @@ -53,6 +54,7 @@ struct event_t {
unsigned long timestamp;
process_t process;
char filename[PATH_MAX];
short unsigned int filename_len;
inode_key_t inode;
file_activity_type_t type;
};
Expand Down
26 changes: 20 additions & 6 deletions fact/src/event/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
#[cfg(test)]
use std::time::{SystemTime, UNIX_EPOCH};
use std::{ffi::CStr, os::raw::c_char, path::PathBuf};
use std::{
ffi::{CStr, OsString},
os::{raw::c_char, unix::ffi::OsStringExt},
path::PathBuf,
};

use serde::Serialize;

use fact_ebpf::{event_t, file_activity_type_t, inode_key_t, PATH_MAX};
use fact_ebpf::{event_t, file_activity_type_t, inode_key_t};

use crate::host_info;
use process::Process;

pub(crate) mod process;

fn slice_to_pathbuf(s: &[c_char]) -> PathBuf {
#[cfg(target_arch = "x86_64")]
let v = s.iter().map(|c| *c as u8).collect::<Vec<u8>>();
#[cfg(not(target_arch = "x86_64"))]
let v = s.to_vec();
OsString::from_vec(v).into()
}

fn slice_to_string(s: &[c_char]) -> anyhow::Result<String> {
Ok(unsafe { CStr::from_ptr(s.as_ptr()) }.to_str()?.to_owned())
}
Expand Down Expand Up @@ -85,7 +97,9 @@ impl TryFrom<&event_t> for Event {
fn try_from(value: &event_t) -> Result<Self, Self::Error> {
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.inode)?;
let filename_len = value.filename_len as usize;
let (filename, _) = value.filename.as_slice().split_at(filename_len - 1);
let file = FileData::new(value.type_, filename, value.inode)?;

Ok(Event {
timestamp,
Expand Down Expand Up @@ -128,7 +142,7 @@ pub enum FileData {
impl FileData {
pub fn new(
event_type: file_activity_type_t,
filename: [c_char; PATH_MAX as usize],
filename: &[c_char],
inode: inode_key_t,
) -> anyhow::Result<Self> {
let inner = BaseFileData::new(filename, inode)?;
Expand Down Expand Up @@ -185,8 +199,8 @@ pub struct BaseFileData {
}

impl BaseFileData {
pub fn new(filename: [c_char; PATH_MAX as usize], inode: inode_key_t) -> anyhow::Result<Self> {
let filename = slice_to_string(&filename)?.into();
pub fn new(filename: &[c_char], inode: inode_key_t) -> anyhow::Result<Self> {
let filename = slice_to_pathbuf(filename);

Ok(BaseFileData {
filename,
Expand Down
18 changes: 8 additions & 10 deletions fact/src/event/process.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use std::ffi::CStr;
use std::{ffi::CStr, path::PathBuf};

use fact_ebpf::{lineage_t, process_t};
use serde::Serialize;
use uuid::Uuid;

use crate::host_info;

use super::slice_to_string;
use super::{slice_to_pathbuf, slice_to_string};

#[derive(Debug, Clone, Default, Serialize)]
pub struct Lineage {
Expand Down Expand Up @@ -48,7 +48,7 @@ impl From<Lineage> for fact_api::process_signal::LineageInfo {
pub struct Process {
comm: String,
args: Vec<String>,
exe_path: String,
exe_path: PathBuf,
container_id: Option<String>,
uid: u32,
username: &'static str,
Expand All @@ -66,11 +66,7 @@ impl Process {
pub fn current() -> Self {
use crate::host_info::{get_host_mount_ns, get_mount_ns};

let exe_path = std::env::current_exe()
.expect("Failed to get current exe")
.into_os_string()
.into_string()
.unwrap();
let exe_path = std::env::current_exe().expect("Failed to get current exe");
let args = std::env::args().collect::<Vec<_>>();
let cgroup = std::fs::read_to_string("/proc/self/cgroup").expect("Failed to read cgroup");
let container_id = Process::extract_container_id(&cgroup);
Expand Down Expand Up @@ -142,7 +138,9 @@ impl TryFrom<process_t> for Process {

fn try_from(value: process_t) -> Result<Self, Self::Error> {
let comm = slice_to_string(value.comm.as_slice())?;
let exe_path = slice_to_string(value.exe_path.as_slice())?;
let exe_path_len = value.exe_path_len as usize;
let (exe_path, _) = value.exe_path.as_slice().split_at(exe_path_len - 1);
let exe_path = slice_to_pathbuf(exe_path);
let memory_cgroup = unsafe { CStr::from_ptr(value.memory_cgroup.as_ptr()) }.to_str()?;
let container_id = Process::extract_container_id(memory_cgroup);
let in_root_mount_ns = value.in_root_mount_ns != 0;
Expand Down Expand Up @@ -213,7 +211,7 @@ impl From<Process> for fact_api::ProcessSignal {
creation_time: None,
name: comm,
args,
exec_file_path: exe_path,
exec_file_path: exe_path.to_string_lossy().into_owned(),
pid,
uid,
gid,
Expand Down
Loading