diff --git a/crates/cardwire-daemon/src/analyzer/models.rs b/crates/cardwire-daemon/src/analyzer/models.rs index 7cf36588..5cad4f30 100644 --- a/crates/cardwire-daemon/src/analyzer/models.rs +++ b/crates/cardwire-daemon/src/analyzer/models.rs @@ -23,12 +23,6 @@ pub struct ExecEvent { pub pid: u32, } -#[repr(C)] -#[derive(Debug, Copy, Clone)] -pub struct CloseEvent { - pub pid: u32, -} - #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct ReportEvent { @@ -46,7 +40,6 @@ enum PidType { #[derive(Clone)] pub struct CardwireAnalyzer { exec_ring: Arc>>>, - close_ring: Arc>>>, report_ring: Arc>>>, pid_map: Arc>>, forced_map: Arc>>, @@ -73,19 +66,16 @@ impl CardwireAnalyzer { ) -> anyhow::Result { let mut blocker = blocker.write().await; let exec_ring = blocker.get_exec_ring()?; - let close_ring = blocker.get_close_ring()?; let report_ring = blocker.get_report_ring()?; let pid_map = Arc::clone(&blocker.pid_map); let forced_map = Arc::clone(&blocker.forced_map); let ebpf_logger = blocker.get_ebpf_logger()?; let exec_ring = AsyncFd::new(exec_ring)?; - let close_ring = AsyncFd::new(close_ring)?; let report_ring = AsyncFd::new(report_ring)?; // Now Rwlock -> Arc let exec_ring = Arc::new(Mutex::new(exec_ring)); - let close_ring = Arc::new(Mutex::new(close_ring)); let report_ring = Arc::new(Mutex::new(report_ring)); let ebpf_logger: Arc>>> = Arc::new(Mutex::new(ebpf_logger)); @@ -95,7 +85,6 @@ impl CardwireAnalyzer { let xdg_folders: Vec = xdg_result.1; Ok(CardwireAnalyzer { exec_ring, - close_ring, report_ring, pid_map, forced_map, @@ -111,12 +100,10 @@ impl CardwireAnalyzer { pub async fn run(self) -> anyhow::Result<()> { // Clone the Arcs and Sender to move into the background task let exec_arc = self.exec_ring.clone(); - let close_arc = self.close_ring.clone(); let logger_arc = self.ebpf_logger.clone(); // Lock the buffers once let mut exec_ring = exec_arc.lock().await; - let mut close_ring = close_arc.lock().await; let shared_self = Arc::new(self); @@ -141,40 +128,19 @@ impl CardwireAnalyzer { task::spawn(async move { shared_self_report.report_logger().await }); loop { - tokio::select! { - Ok(mut guard) = exec_ring.ready_mut(Interest::READABLE) => { - if guard.ready().is_readable() { - while let Some(item) = guard.get_inner_mut().next() { - if item.len() < std::mem::size_of::() { - debug!("Skipping malformed exec event. Size: {}", item.len()); - continue; - } - let event = unsafe { ptr::read_unaligned(item.as_ptr() as *const ExecEvent) }; - let this = Arc::clone(&shared_self); - task::spawn(async move { - this.spawn_exec_analyzer(event).await - }); - } - guard.clear_ready(); - } - } - - Ok(mut guard) = close_ring.ready_mut(Interest::READABLE) => { - if guard.ready().is_readable() { - while let Some(item) = guard.get_inner_mut().next() { - if item.len() < std::mem::size_of::() { - debug!("Skipping malformed close event. Size: {}", item.len()); - continue; - } - let event = unsafe { ptr::read_unaligned(item.as_ptr() as *const CloseEvent) }; - let this = Arc::clone(&shared_self); - task::spawn(async move { - this.spawn_remove_analyzer(event).await - }); - } - guard.clear_ready(); + if let Ok(mut guard) = exec_ring.ready_mut(Interest::READABLE).await + && guard.ready().is_readable() + { + while let Some(item) = guard.get_inner_mut().next() { + if item.len() < std::mem::size_of::() { + debug!("Skipping malformed exec event. Size: {}", item.len()); + continue; } + let event = unsafe { ptr::read_unaligned(item.as_ptr() as *const ExecEvent) }; + let this = Arc::clone(&shared_self); + task::spawn(async move { this.spawn_exec_analyzer(event).await }); } + guard.clear_ready(); } } } @@ -216,26 +182,6 @@ impl CardwireAnalyzer { } } } - async fn spawn_remove_analyzer(&self, event: CloseEvent) -> () { - { - let mut pid_map = self.pid_map.write().await; - if pid_map.remove(&event.pid).is_ok() { - debug!("REMOVE: pid: {}", event.pid); - } - } - { - let mut forced_map = self.forced_map.write().await; - if forced_map.remove(&event.pid).is_ok() { - debug!("REMOVE FORCED: pid: {}", event.pid); - } - } - { - let mut reported_pid_map = self.reported_pids.write().await; - if reported_pid_map.remove(&event.pid) { - debug!("REMOVE REPORTED: pid: {}", event.pid); - } - } - } async fn report_logger(&self) -> () { let report_arc = self.report_ring.clone(); @@ -492,16 +438,6 @@ mod tests { assert_eq!(event.pid, u32::MAX); } - #[test] - fn test_close_event_deserialization() { - let item: Vec = vec![ - 0x2A, 0x00, 0x00, 0x00, // pid = 42 - ]; - assert!(item.len() >= std::mem::size_of::()); - let event = unsafe { ptr::read_unaligned(item.as_ptr() as *const CloseEvent) }; - assert_eq!(event.pid, 42); - } - #[test] fn test_get_real_process_name_returns_exe_for_wine_proton_cmdline() { let cmdline_bytes = diff --git a/crates/cardwire-ebpf-userspace/src/lib.rs b/crates/cardwire-ebpf-userspace/src/lib.rs index 68f89283..d7eb6b99 100644 --- a/crates/cardwire-ebpf-userspace/src/lib.rs +++ b/crates/cardwire-ebpf-userspace/src/lib.rs @@ -292,28 +292,6 @@ impl EbpfBlocker { Ok(ring_buf) } - /// take the CW_CLOSE_EVENTS RingBuf map from the blocker - pub fn get_close_ring(&mut self) -> CardwireEbpfResult> { - let map_str = "CW_CLOSE_EVENTS"; - let map = match self.ebpf.take_map(map_str) { - Some(map) => map, - None => { - error!("error while trying to take map {}", map_str); - return Err(CardwireEbpfError::MissingMap { - name: map_str.to_string(), - }); - } - }; - let ring_buf: RingBuf = match RingBuf::try_from(map) { - Ok(ringbuf) => ringbuf, - Err(err) => { - error!("error while trying to get the close ring_buf"); - return Err(CardwireEbpfError::aya(err)); - } - }; - Ok(ring_buf) - } - /// take the CW_REPORT_EVENTS RingBuf map from the blocker pub fn get_report_ring(&mut self) -> CardwireEbpfResult> { let map_str = "CW_REPORT_EVENTS"; diff --git a/crates/cardwire-ebpf/src/main.rs b/crates/cardwire-ebpf/src/main.rs index 61ace756..07f0d902 100644 --- a/crates/cardwire-ebpf/src/main.rs +++ b/crates/cardwire-ebpf/src/main.rs @@ -7,7 +7,7 @@ use aya_ebpf::{ use aya_log_ebpf::{error, warn}; use crate::{ - helpers::{is_cardwired, is_comm_whitelisted, is_hybrid, is_inode_blocked, is_smart}, maps::{CW_CLOSE_EVENTS, CW_DIRENT, CW_EXEC_EVENTS, CloseEvent, ExecEvent}, vmlinux::{dentry, file, inode, linux_dirent64, path} + helpers::{is_cardwired, is_comm_whitelisted, is_hybrid, is_inode_blocked, is_smart}, maps::{CW_ALLOWED_PID, CW_DIRENT, CW_EXEC_EVENTS, CW_FORCED_PID, ExecEvent}, vmlinux::{dentry, file, inode, linux_dirent64, path} }; #[allow( @@ -424,6 +424,10 @@ pub fn tracepoint_sched_process_exec(ctx: TracePointContext) -> u32 { } unsafe fn try_tracepoint_sched_process_exec(ctx: TracePointContext) -> Result { + // First we clean the MAP + let pid = (bpf_get_current_pid_tgid() >> 32) as u32; + let _ = CW_ALLOWED_PID.remove(&pid); + let _ = CW_FORCED_PID.remove(&pid); // If it's the daemon, we must exit match is_cardwired() { Some(res) => { @@ -459,7 +463,6 @@ unsafe fn try_tracepoint_sched_process_exec(ctx: TracePointContext) -> Result> 32) as u32; // We just send the event to userspace let event: ExecEvent = ExecEvent { pid }; @@ -480,38 +483,18 @@ pub fn tracepoint_sched_process_exit(ctx: TracePointContext) -> u32 { } } -unsafe fn try_tracepoint_sched_process_exit(ctx: TracePointContext) -> Result { - // Only proceed if we are in smart mode, events are not used when not in smart mode and it would - // slow down the system for no reason - if let Some(res) = unsafe { is_smart() } - && res - { - let pid_tgid: u64 = bpf_get_current_pid_tgid(); - let tgid = pid_tgid as u32; - let pid = (pid_tgid >> 32) as u32; - - // Only send close event if the main thread is exiting - if pid != tgid { - return ReturnCode::SUCCESS; - } - - let event: CloseEvent = CloseEvent { pid }; +unsafe fn try_tracepoint_sched_process_exit(_ctx: TracePointContext) -> Result { + let pid_tgid: u64 = bpf_get_current_pid_tgid(); + let tgid = pid_tgid as u32; + let pid = (pid_tgid >> 32) as u32; - let mut ring_buf = match CW_CLOSE_EVENTS.reserve(0) { - Some(ring_buf) => ring_buf, - // Reservation fail, warn and leave - None => { - warn!( - &ctx, - "failed to reserve bytes for ring_buf: CW_CLOSE_EVENTS" - ); - return ReturnCode::SUCCESS; - } - }; - - ring_buf.write(event); - ring_buf.submit(0); + // Only process the exit if the main thread is exiting + if pid != tgid { + return ReturnCode::SUCCESS; } + // Remove PID from the maps + let _ = CW_ALLOWED_PID.remove(&pid); + let _ = CW_FORCED_PID.remove(&pid); ReturnCode::SUCCESS } diff --git a/crates/cardwire-ebpf/src/maps.rs b/crates/cardwire-ebpf/src/maps.rs index 317507c8..56107ce7 100644 --- a/crates/cardwire-ebpf/src/maps.rs +++ b/crates/cardwire-ebpf/src/maps.rs @@ -80,15 +80,6 @@ pub struct ExecEvent { #[btf_map] pub static CW_EXEC_EVENTS: RingBuf = RingBuf::new(); -#[repr(align(8))] -#[allow(dead_code)] -pub struct CloseEvent { - pub pid: u32, -} - -#[btf_map] -pub static CW_CLOSE_EVENTS: RingBuf = RingBuf::new(); - #[repr(C)] #[repr(align(8))] #[allow(dead_code)]