diff --git a/crates/cardwire-daemon/src/models.rs b/crates/cardwire-daemon/src/models.rs index d30bec0..5e0c1e7 100644 --- a/crates/cardwire-daemon/src/models.rs +++ b/crates/cardwire-daemon/src/models.rs @@ -15,6 +15,9 @@ use zbus::{ fdo::{self}, interface }; +// shouldn't be necessary anymore +const ALLOWED_PROGRAMS: &[&str] = &["(udev-worker)", "pacman", "nix", "dnf", "apt"]; + #[derive(Clone)] pub struct DaemonManager { pub mode_interface: ModeInterface, @@ -133,6 +136,10 @@ impl DaemonManager { } } + for comm in ALLOWED_PROGRAMS { + blocker.allow_comm(comm)?; + } + drop(blocker); let default: bool = state.is_default_state(); diff --git a/crates/cardwire-ebpf/src/bpf.h b/crates/cardwire-ebpf/src/bpf.h index 729767b..4f90cb6 100644 --- a/crates/cardwire-ebpf/src/bpf.h +++ b/crates/cardwire-ebpf/src/bpf.h @@ -88,7 +88,7 @@ struct report_t { }; // EBPF maps -// This one is to report the events to cardwire +// This one is to report the events to cardwired smart mode struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); @@ -129,6 +129,7 @@ struct { __type(value, __u8); } cw_mode SEC(".maps"); +// Used to store the blocked inos struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 2048); @@ -136,6 +137,7 @@ struct { __type(value, __u8); } cw_blocked_ino SEC(".maps"); +// This struct contains the inodes of the blocked experimental nvidia files struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 2048); @@ -155,6 +157,7 @@ struct { __type(value, __u8); } cw_settings SEC(".maps"); +// Struct that contains cardwired's pid struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, 1); @@ -168,3 +171,11 @@ struct { __type(key, __u32); __type(value, __u64); } cw_dirent SEC(".maps"); + +// This one contain whitelist programs comm's +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 2048); + __type(key, char[16]); + __type(value, __u8); +} cw_allowed_comm SEC(".maps"); \ No newline at end of file diff --git a/crates/cardwire-ebpf/src/helpers.h b/crates/cardwire-ebpf/src/helpers.h index 79974ee..43a9155 100644 --- a/crates/cardwire-ebpf/src/helpers.h +++ b/crates/cardwire-ebpf/src/helpers.h @@ -46,8 +46,7 @@ static __always_inline int is_process_whitelisted() { char comm[16] = {}; bpf_get_current_comm(comm, sizeof(comm)); - // whitelist udev for pci hotplug - if (__builtin_memcmp(comm, "(udev-worker)", 13) == 0) { + if (bpf_map_lookup_elem(&cw_allowed_comm, &comm)) { return true; } return false; diff --git a/crates/cardwire-ebpf/src/lib.rs b/crates/cardwire-ebpf/src/lib.rs index 714b95a..c617876 100644 --- a/crates/cardwire-ebpf/src/lib.rs +++ b/crates/cardwire-ebpf/src/lib.rs @@ -190,6 +190,28 @@ impl EbpfBlocker { .map_err(CardwireEbpfError::aya) } + pub fn allow_comm(&mut self, comm: &str) -> CardwireEbpfResult<()> { + // turn the comm str into a char[16] + let comm = { + let mut key = [0u8; 16]; + let bytes = comm.as_bytes(); + // leave one byte for terminator + let len = bytes.len().min(15); + key[..len].copy_from_slice(&bytes[..len]); + key[len] = 0; + key + }; + let mut allowed_comm_map: HashMap<_, [u8; 16], u8> = HashMap::try_from( + self.ebpf + .map_mut("cw_allowed_comm") + .ok_or_else(|| CardwireEbpfError::missing_map("cw_allowed_comm"))?, + ) + .map_err(CardwireEbpfError::aya)?; + allowed_comm_map + .insert(comm, 0, 0) + .map_err(CardwireEbpfError::aya) + } + pub fn get_exec_ring(&mut self) -> CardwireEbpfResult> { let map = self.ebpf.take_map("cw_exec_events").unwrap(); let ring_buf: RingBuf = RingBuf::try_from(map).unwrap();