From 77562fb51a878e0736bff6254906b24e72a683f9 Mon Sep 17 00:00:00 2001 From: Tom Weisshuhn Date: Sun, 17 Nov 2024 22:26:34 +0100 Subject: [PATCH 1/3] [none working] implemented retprbe --- rust/backend/common/src/lib.rs | 27 +++++++++-- rust/backend/ebpf/src/lib.rs | 2 +- rust/backend/ebpf/src/main.rs | 2 +- rust/backend/ebpf/src/vfs_tracing.rs | 71 +++++++++++++++++++++------- 4 files changed, 77 insertions(+), 25 deletions(-) diff --git a/rust/backend/common/src/lib.rs b/rust/backend/common/src/lib.rs index 7fd9c149..232e0ebe 100644 --- a/rust/backend/common/src/lib.rs +++ b/rust/backend/common/src/lib.rs @@ -15,9 +15,26 @@ pub enum KProbeTypes { #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct KProbeData { - pub pid: u32, - pub tid: u32, - pub probe_type: KProbeTypes, - pub ret: bool, +pub struct VfsWriteCall { + pid: u32, + tid: u32, + begin_time_stamp: u64, + fd: i32, + bytes_written: usize, } + +impl VfsWriteCall { + pub fn new(pid: u32, tid: u32, begin_time_stamp: u64, fd: i32, bytes_written: usize) -> Self { + Self { pid, tid, begin_time_stamp, fd, bytes_written} + } +} + +#[inline(always)] +pub fn generate_id(pid: u32, tgid: u32) -> u64{ + let pid_u64 = pid as u64; + let tgid_u64 = tgid as u64; + + (pid_u64 << 32) | tgid_u64 +} + + diff --git a/rust/backend/ebpf/src/lib.rs b/rust/backend/ebpf/src/lib.rs index ab864d14..3b6efc19 100644 --- a/rust/backend/ebpf/src/lib.rs +++ b/rust/backend/ebpf/src/lib.rs @@ -10,4 +10,4 @@ mod vfs_tracing; -pub use vfs_tracing::{vfs_write, KPROBES}; +pub use vfs_tracing::{vfs_write, VFS_WRITE_MAP}; diff --git a/rust/backend/ebpf/src/main.rs b/rust/backend/ebpf/src/main.rs index 9b2e3ca2..cc2d9e11 100644 --- a/rust/backend/ebpf/src/main.rs +++ b/rust/backend/ebpf/src/main.rs @@ -14,7 +14,7 @@ use aya_ebpf::{ maps::{PerCpuArray, RingBuf}, programs::XdpContext, }; -pub use backend_ebpf::{vfs_write, KPROBES}; +pub use backend_ebpf::{vfs_write, VFS_WRITE_MAP}; #[map(name = "COUNTER")] static PACKET_COUNTER: PerCpuArray = PerCpuArray::with_max_entries(1, 0); diff --git a/rust/backend/ebpf/src/vfs_tracing.rs b/rust/backend/ebpf/src/vfs_tracing.rs index 60650912..c29f163c 100644 --- a/rust/backend/ebpf/src/vfs_tracing.rs +++ b/rust/backend/ebpf/src/vfs_tracing.rs @@ -2,35 +2,70 @@ // // SPDX-License-Identifier: MIT + + +const TIME_LIMIT_NS: u64 = 100_000_000; + +use core::ffi::{c_int, c_size_t}; use aya_ebpf::{ macros::{kprobe, map}, - maps::RingBuf, + maps::{HashMap, RingBuf}, programs::ProbeContext, EbpfContext, + helpers::gen::bpf_ktime_get_ns, }; -use backend_common::{KProbeData, KProbeTypes}; +use backend_common::{generate_id, VfsWriteCall}; + + + +#[map(name = "VFS_WRITE_MAP")] +pub static VFS_WRITE_MAP: RingBuf = RingBuf::with_byte_size(1024, 0); +#[map(name = "VFS_WRITE_INTERN")] +pub static VFS_WRITE_TIMESTAMPS: HashMap = HashMap::with_max_entries(1024, 0); -#[map(name = "Kprobes")] -pub static KPROBES: RingBuf = RingBuf::with_byte_size(1024, 0); #[kprobe] pub fn vfs_write(ctx: ProbeContext) -> Result<(), u32> { - let pid = ctx.pid(); - let tid = ctx.tgid(); + let id = generate_id(ctx.pid(), ctx.tgid()); + let time_stamp = unsafe {bpf_ktime_get_ns()}; - let data = KProbeData { - pid, - tid, - probe_type: KProbeTypes::VfsWrite, - ret: false, - }; - let mut entry = match KPROBES.reserve::(0) { - Some(entry) => entry, - None => return Err(0), + match VFS_WRITE_TIMESTAMPS.insert(&id, &time_stamp, 0) { + Ok(_) => Ok(()), + Err(_) => Err(0), + } + +} + + +#[kprobe] +pub fn vfs_write_ret(ctx: ProbeContext) -> Result<(), u32> { + let probe_end = unsafe { bpf_ktime_get_ns() }; + + let pid = ctx.pid(); + let tgid = ctx.tgid(); + let call_id = generate_id(pid, tgid); + let probe_start = match unsafe { VFS_WRITE_TIMESTAMPS.get(&call_id) } { + None => {return Err(0)} + Some(time_stamp) => {time_stamp.clone()} }; - entry.write(data); - entry.submit(0); + if probe_start - probe_end > TIME_LIMIT_NS { + let fd: c_int = ctx.arg(0).unwrap(); + let count: c_size_t = ctx.arg(2).unwrap(); + + + + let data = VfsWriteCall::new(pid, tgid, probe_start, fd as i32, count as usize); + + + let mut entry = match VFS_WRITE_MAP.reserve::(0) { + Some(entry) => entry, + None => return Err(0), + }; + + entry.write(data); + entry.submit(0); + } Ok(()) -} +} \ No newline at end of file From 434f4bbe9ee86146875ecaf273b0a80687837c31 Mon Sep 17 00:00:00 2001 From: Tom Weisshuhn Date: Sun, 17 Nov 2024 23:06:41 +0100 Subject: [PATCH 2/3] chore(eBPF) moved fetching call args from retprobe to probe --- rust/backend/ebpf/src/vfs_tracing.rs | 33 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/rust/backend/ebpf/src/vfs_tracing.rs b/rust/backend/ebpf/src/vfs_tracing.rs index c29f163c..3cb49652 100644 --- a/rust/backend/ebpf/src/vfs_tracing.rs +++ b/rust/backend/ebpf/src/vfs_tracing.rs @@ -6,7 +6,6 @@ const TIME_LIMIT_NS: u64 = 100_000_000; -use core::ffi::{c_int, c_size_t}; use aya_ebpf::{ macros::{kprobe, map}, maps::{HashMap, RingBuf}, @@ -20,16 +19,29 @@ use backend_common::{generate_id, VfsWriteCall}; #[map(name = "VFS_WRITE_MAP")] pub static VFS_WRITE_MAP: RingBuf = RingBuf::with_byte_size(1024, 0); -#[map(name = "VFS_WRITE_INTERN")] -pub static VFS_WRITE_TIMESTAMPS: HashMap = HashMap::with_max_entries(1024, 0); + + +#[map(name = "VfsWriteIntern")] +static VFS_WRITE_TIMESTAMPS: HashMap = HashMap::with_max_entries(1024, 0); + + +struct VfsWriteIntern { + begin_time_stamp: u64, + fd: i32, + bytes_written: usize, +} #[kprobe] pub fn vfs_write(ctx: ProbeContext) -> Result<(), u32> { let id = generate_id(ctx.pid(), ctx.tgid()); - let time_stamp = unsafe {bpf_ktime_get_ns()}; + let data = VfsWriteIntern { + begin_time_stamp: unsafe {bpf_ktime_get_ns()}, + fd: ctx.arg(0).unwrap_or(-1), + bytes_written: ctx.arg(2).unwrap_or(usize::MAX) as usize, + }; - match VFS_WRITE_TIMESTAMPS.insert(&id, &time_stamp, 0) { + match VFS_WRITE_TIMESTAMPS.insert(&id, &data, 0) { Ok(_) => Ok(()), Err(_) => Err(0), } @@ -44,18 +56,15 @@ pub fn vfs_write_ret(ctx: ProbeContext) -> Result<(), u32> { let pid = ctx.pid(); let tgid = ctx.tgid(); let call_id = generate_id(pid, tgid); - let probe_start = match unsafe { VFS_WRITE_TIMESTAMPS.get(&call_id) } { + let data = match unsafe { VFS_WRITE_TIMESTAMPS.get(&call_id) } { None => {return Err(0)} - Some(time_stamp) => {time_stamp.clone()} + Some(entry) => {entry} }; - if probe_start - probe_end > TIME_LIMIT_NS { - let fd: c_int = ctx.arg(0).unwrap(); - let count: c_size_t = ctx.arg(2).unwrap(); - + if data.begin_time_stamp - probe_end > TIME_LIMIT_NS { - let data = VfsWriteCall::new(pid, tgid, probe_start, fd as i32, count as usize); + let data = VfsWriteCall::new(pid, tgid, data.begin_time_stamp, data.fd, data.bytes_written); let mut entry = match VFS_WRITE_MAP.reserve::(0) { From a2e426b4631b7a9c4ea55ac7ac5066269348af3d Mon Sep 17 00:00:00 2001 From: Tom Weisshuhn Date: Tue, 19 Nov 2024 16:59:59 +0100 Subject: [PATCH 3/3] chore(eBPF) fixed return KProbe time difference Signed-off-by: Tom Weisshuhn --- rust/backend/ebpf/src/vfs_tracing.rs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/rust/backend/ebpf/src/vfs_tracing.rs b/rust/backend/ebpf/src/vfs_tracing.rs index 3cb49652..61a1747d 100644 --- a/rust/backend/ebpf/src/vfs_tracing.rs +++ b/rust/backend/ebpf/src/vfs_tracing.rs @@ -7,12 +7,13 @@ const TIME_LIMIT_NS: u64 = 100_000_000; use aya_ebpf::{ - macros::{kprobe, map}, + macros::{kprobe, map, kretprobe}, maps::{HashMap, RingBuf}, - programs::ProbeContext, + programs::{ProbeContext, RetProbeContext}, EbpfContext, helpers::gen::bpf_ktime_get_ns, }; +use aya_log_ebpf::info; use backend_common::{generate_id, VfsWriteCall}; @@ -31,7 +32,6 @@ struct VfsWriteIntern { bytes_written: usize, } - #[kprobe] pub fn vfs_write(ctx: ProbeContext) -> Result<(), u32> { let id = generate_id(ctx.pid(), ctx.tgid()); @@ -49,8 +49,8 @@ pub fn vfs_write(ctx: ProbeContext) -> Result<(), u32> { } -#[kprobe] -pub fn vfs_write_ret(ctx: ProbeContext) -> Result<(), u32> { +#[kretprobe] +pub fn vfs_write_ret(ctx: RetProbeContext) -> Result<(), u32> { let probe_end = unsafe { bpf_ktime_get_ns() }; let pid = ctx.pid(); @@ -61,12 +61,9 @@ pub fn vfs_write_ret(ctx: ProbeContext) -> Result<(), u32> { Some(entry) => {entry} }; - if data.begin_time_stamp - probe_end > TIME_LIMIT_NS { - - + if probe_end - data.begin_time_stamp > TIME_LIMIT_NS { let data = VfsWriteCall::new(pid, tgid, data.begin_time_stamp, data.fd, data.bytes_written); - let mut entry = match VFS_WRITE_MAP.reserve::(0) { Some(entry) => entry, None => return Err(0),