Skip to content

Commit

Permalink
ebpf: track fd creations/destruction
Browse files Browse the repository at this point in the history
Signed-off-by: Tom Weisshuhn <tom.weisshuhn@fau.de>
  • Loading branch information
der-whity committed Jan 19, 2025
1 parent 6bb7343 commit 084d1df
Showing 4 changed files with 112 additions and 9 deletions.
22 changes: 22 additions & 0 deletions rust/backend/common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -131,6 +131,8 @@ impl SysSigquitCall {
}
}


// garbage collection
#[repr(C)]
#[derive(Debug, Copy, Clone, CheckedBitPattern)]
pub struct SysGcCall {
@@ -139,6 +141,26 @@ pub struct SysGcCall {
pub heap: Heap
}


// ---------------------------------------
// SysFdTracking: track the creation/ destruction of file descriptors

#[repr(u8)]
#[derive(Debug, Copy, Clone, CheckedBitPattern)]
pub enum SysFdAction {
Created,
Destroyed,
}

#[repr(C)]
#[derive(Debug, Copy, Clone, CheckedBitPattern)]
pub struct SysFdActionCall {
pub pid: u32,
pub tid: u32,
pub time_stamp: u64,
pub fd_action: SysFdAction,
}

// ----------------------------------
// generate a unique id from pid and tid
#[inline(always)]
17 changes: 9 additions & 8 deletions rust/backend/ebpf/README.md
Original file line number Diff line number Diff line change
@@ -9,14 +9,15 @@ SPDX-License-Identifier: MIT

The entries in the maps are the structs defined in `../common/src/lib.rs`.
The maps `<hook-name>_PIDS` are HashMaps that store the pid as key and as value the duration for a call to be considered blocking in nanosec.
For the features `SIGQUIT` and `JNIReferences` the durations are irrelevant as they are not relevant for the use-cases.
For the features `SIGQUIT` and `JNIReferences` the durations are irrelevant as they are not relevant for the use-cases.

## overview by hook name

| | type | functions to hook | map<entry-type> |
|---------------|------------|------------------------------------------------------------------------------|-------------------------------------|
| vfs_write | KProbe | `vfs_write`, `vfs_write_ret` | `VFS_WRITE_EVENTS<VfsWriteCall>` |
| sendmsg | Tracepoint | `sys_enter_sendmsg`, `sys_exit_sendmsg` | `SYS_SENDMSG_CALLS<SysSendmsgCall>` |
| SIGQUIT | Tracepoint | `sys_sigquit` | `SYS_SIGQUIT_CALLS<SysSigquitCall>` |
| JNIReferences | UProbe | `trace_add_local`, `trace_del_local`, `trace_add_global`, `trace_del_global` | `JNI_REF_CALLS<JNIRefCall>` |
| ... | ... | ... | ... |
| | type | functions to hook | map<entry-type> |
|---------------|------------|----------------------------------------------------------------------------|------------------------------------------|
| vfs_write | KProbe | `vfs_write`, `vfs_write_ret` | `VFS_WRITE_EVENTS<VfsWriteCall>` |
| sendmsg | Tracepoint | `sys_enter_sendmsg`, `sys_exit_sendmsg` | `SYS_SENDMSG_CALLS<SysSendmsgCall>` |
| SIGQUIT | Tracepoint | `sys_sigquit` | `SYS_SIGQUIT_CALLS<SysSigquitCall>` |
| fd_tracking | Tracepoint | `sys_create_fd`, `sys_fd_destroy` | `SYS_FDTRACKING_EVENTS<SysFdActionCall>` |
| JNIReferences | UProbe | `trace_add_local`, `trace_del_local`, `trace_add_global`, `trace_del_global` | `JNI_REF_CALLS<JNIRefCall>` |
| ... | ... | ... | ... |
4 changes: 3 additions & 1 deletion rust/backend/ebpf/src/lib.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
// SPDX-FileCopyrightText: 2024 Benedikt Zinn <benedikt.wh.zinn@gmail.com>
// SPDX-FileCopyrightText: 2024 Felix Hilgers <felix.hilgers@fau.de>
// SPDX-FileCopyrightText: 2024 Luca Bretting <luca.bretting@fau.de>
// SPDX-FileCopyrightText: 2024 Tom Weisshuhn <tom.weisshuhn@fau.de>
//
// SPDX-License-Identifier: MIT

@@ -12,4 +13,5 @@ pub mod vfs_write;
pub mod sys_sendmsg;
pub mod jni_references;
pub mod sys_sigquit;
pub mod garbage_collection;
pub mod garbage_collection;
pub mod sys_fd_tracking;
78 changes: 78 additions & 0 deletions rust/backend/ebpf/src/sys_fd_tracking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-FileCopyrightText: 2024 Tom Weisshuhn <tom.weisshuhn@fau.de>
//
// SPDX-License-Identifier: MIT

use aya_ebpf::{helpers::gen::bpf_ktime_get_ns, macros::map, maps::RingBuf, programs::TracePointContext, EbpfContext};
use aya_ebpf::maps::HashMap;
use aya_log_ebpf::error;
use backend_common::{SysFdAction, SysFdActionCall};

#[map(name = "SYS_FDTRACKING_PIDS")]
static SYS_FDTRACKING_PIDS: HashMap<u32, u64> = HashMap::pinned(4096, 0);

#[map(name = "SYS_FDTRACKING_EVENTS")]
pub static SYS_FDTRACKING_EVENTS: RingBuf = RingBuf::pinned(1024, 0);

// Disclaimer:
// We have to swap here, because BPF_PROG_TEST_RUN does not support Tracepoints
// For testing we can set the prog-test flag and interpret it as TracepointContext, because we can set whatever we want
// For an example see backend/daemon/src/prog_test_run.rs

#[cfg(feature = "prog-test")]
type Arg = aya_ebpf::programs::RawTracePointContext;

#[cfg(not(feature = "prog-test"))]
type Arg = aya_ebpf::programs::TracePointContext;

#[cfg_attr(feature = "prog-test", aya_ebpf::macros::raw_tracepoint)]
#[cfg_attr(not(feature = "prog-test"), aya_ebpf::macros::tracepoint)]
pub fn sys_create_fd(ctx: Arg) -> u32 {
let ctx = TracePointContext::new(ctx.as_ptr());
handle_fd_action(ctx, SysFdAction::Created)
}


#[cfg_attr(feature = "prog-test", aya_ebpf::macros::raw_tracepoint)]
#[cfg_attr(not(feature = "prog-test"), aya_ebpf::macros::tracepoint)]
pub fn sys_destroy_fd(ctx: Arg) -> u32 {
let ctx = TracePointContext::new(ctx.as_ptr());
handle_fd_action(ctx, SysFdAction::Destroyed)
}


fn handle_fd_action(ctx: TracePointContext, fd_action: SysFdAction) -> u32 {
let pid = ctx.pid();

if pid < 2700 {
return 1;
}
//if unsafe { SYS_FDTRACKING_PIDS.get(&pid).is_none() } {
// ignore signals from this pid
// return 0;
//}

let tid = ctx.tgid();

let time_stamp: u64 = unsafe { bpf_ktime_get_ns() };

let mut entry = match SYS_FDTRACKING_EVENTS.reserve::<SysFdActionCall>(0) {
Some(entry) => entry,
None => {
error!(&ctx, "could not reserve space in map: SYS_FDTRACKING_CALLS");
return 1;
}
};

let entry_mut = entry.as_mut_ptr();

unsafe {
(&raw mut (*entry_mut).pid).write(pid);
(&raw mut (*entry_mut).tid).write(tid);
(&raw mut (*entry_mut).time_stamp).write(time_stamp);
(&raw mut (*entry_mut).fd_action).write(fd_action);
}

entry.submit(0);

0
}

0 comments on commit 084d1df

Please sign in to comment.