From 6bea191b8d2b4a694a7cd5c4675969e8978b3f0e Mon Sep 17 00:00:00 2001 From: qjerome Date: Thu, 19 Dec 2024 12:32:08 +0100 Subject: [PATCH 1/2] refactor: turn error event into log event - more accurate terminology as a log can be either info/warn/error - refactored eBPF error and warn macro to handle all the cases - removed error_msg and warn_msg macros - renamed structures and enums to turn "error" terminology to "log" --- kunai-common/src/bpf_events.rs | 4 +- kunai-common/src/bpf_events/events.rs | 6 +- .../bpf_events/events/{error.rs => log.rs} | 10 +-- kunai-common/src/bpf_events/events/perfs.rs | 4 +- kunai-common/src/errors/bpf.rs | 66 ++++++++----------- kunai-ebpf/src/probes.rs | 4 +- kunai-ebpf/src/probes/bpf.rs | 6 +- kunai-ebpf/src/probes/bpf_socket.rs | 2 +- kunai-ebpf/src/probes/execve.rs | 2 +- kunai-ebpf/src/probes/fs.rs | 8 +-- kunai-ebpf/src/probes/init_module.rs | 2 +- kunai-ebpf/src/probes/schedule.rs | 2 +- kunai/src/bin/main.rs | 18 +++-- 13 files changed, 65 insertions(+), 69 deletions(-) rename kunai-common/src/bpf_events/events/{error.rs => log.rs} (92%) diff --git a/kunai-common/src/bpf_events.rs b/kunai-common/src/bpf_events.rs index e4051644..9de7e455 100644 --- a/kunai-common/src/bpf_events.rs +++ b/kunai-common/src/bpf_events.rs @@ -134,8 +134,8 @@ pub enum Type { Correlation, #[str("cache_hash")] CacheHash, - #[str("error")] - Error, + #[str("log")] + Log, #[str("syscore_resume")] SyscoreResume, diff --git a/kunai-common/src/bpf_events/events.rs b/kunai-common/src/bpf_events/events.rs index b47f71a0..f4ae8f3b 100644 --- a/kunai-common/src/bpf_events/events.rs +++ b/kunai-common/src/bpf_events/events.rs @@ -30,8 +30,8 @@ mod mount; pub use mount::*; mod prctl; pub use prctl::*; -pub mod error; -pub use error::{ErrorData, ErrorEvent}; +pub mod log; +pub use log::{LogData, LogEvent}; mod syscore_resume; pub use syscore_resume::*; mod kill; @@ -85,7 +85,7 @@ const fn max_bpf_event_size() -> usize { | Type::FileCreate => FileEvent::size_of(), Type::FileRename => FileRenameEvent::size_of(), Type::FileUnlink => UnlinkEvent::size_of(), - Type::Error => ErrorEvent::size_of(), + Type::Log => LogEvent::size_of(), Type::SyscoreResume => SysCoreResumeEvent::size_of(), // these are event types only used in user land Type::Unknown diff --git a/kunai-common/src/bpf_events/events/error.rs b/kunai-common/src/bpf_events/events/log.rs similarity index 92% rename from kunai-common/src/bpf_events/events/error.rs rename to kunai-common/src/bpf_events/events/log.rs index f29b1431..38483132 100644 --- a/kunai-common/src/bpf_events/events/error.rs +++ b/kunai-common/src/bpf_events/events/log.rs @@ -5,16 +5,18 @@ use crate::{ string::String, }; -pub type ErrorEvent = Event; +pub type LogEvent = Event; +#[repr(C)] #[derive(Clone, Copy)] pub enum Level { + Info, Warn, Error, } #[repr(C)] -pub struct ErrorData { +pub struct LogData { pub location: String<32>, pub line: u32, pub level: Level, @@ -28,7 +30,7 @@ bpf_target_code! { const DEFAULT_COMM: String<16> = string::from_static("?"); - impl ErrorEvent { + impl LogEvent { #[inline(always)] pub fn init_with_level(&mut self, level: Level){ let pid_tgid = bpf_get_current_pid_tgid(); @@ -41,7 +43,7 @@ bpf_target_code! { } not_bpf_target_code! { - impl core::fmt::Display for ErrorEvent { + impl core::fmt::Display for LogEvent { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, diff --git a/kunai-common/src/bpf_events/events/perfs.rs b/kunai-common/src/bpf_events/events/perfs.rs index 6c51c120..86fa0518 100644 --- a/kunai-common/src/bpf_events/events/perfs.rs +++ b/kunai-common/src/bpf_events/events/perfs.rs @@ -4,7 +4,7 @@ pub const KUNAI_EVENTS_MAP: &str = "KUNAI_EVENTS"; pub const KUNAI_STATS_MAP: &str = "KUNAI_STATS"; bpf_target_code! { - use crate::bpf_events::{Event,Type, ErrorEvent}; + use crate::bpf_events::{Event,Type, LogEvent}; use aya_ebpf::{macros::map, maps::{HashMap,PerfEventByteArray}, EbpfContext}; #[map(name = "KUNAI_EVENTS")] @@ -15,7 +15,7 @@ bpf_target_code! { #[inline(always)] - pub unsafe fn pipe_error(ctx: &C, e: &ErrorEvent) { + pub unsafe fn pipe_log(ctx: &C, e: &LogEvent) { EVENTS.output(ctx, e.encode(), 0); } diff --git a/kunai-common/src/errors/bpf.rs b/kunai-common/src/errors/bpf.rs index 3b7ca85f..311251a3 100644 --- a/kunai-common/src/errors/bpf.rs +++ b/kunai-common/src/errors/bpf.rs @@ -1,7 +1,7 @@ use aya_ebpf::{macros::map, maps::LruPerCpuHashMap, EbpfContext}; use crate::{ - bpf_events::{error, ErrorEvent}, + bpf_events::{log, LogEvent}, string::String, }; @@ -9,11 +9,10 @@ use crate::{ use super::*; #[map] -pub static mut ERRORS: LruPerCpuHashMap = - LruPerCpuHashMap::with_max_entries(16, 0); +pub static mut LOGS: LruPerCpuHashMap = LruPerCpuHashMap::with_max_entries(16, 0); -const SIZE: usize = ErrorEvent::size_of(); -pub static EMPTY_ERROR: [u8; SIZE] = [0; SIZE]; +const SIZE: usize = LogEvent::size_of(); +pub static EMPTY_LOG: [u8; SIZE] = [0; SIZE]; #[macro_export] macro_rules! probe_name { @@ -90,27 +89,27 @@ pub struct Args { pub location: String<32>, pub message: Option>, pub err: Option, - pub level: error::Level, + pub level: log::Level, } #[inline(always)] -pub unsafe fn error_with_args(ctx: &C, args: &Args) { - let _ = ERRORS.insert(&0, &(*(EMPTY_ERROR.as_ptr() as *const ErrorEvent)), 0); - if let Some(e) = ERRORS.get_ptr_mut(&0) { +pub unsafe fn log_with_args(ctx: &C, args: &Args) { + let _ = LOGS.insert(&0, &(*(EMPTY_LOG.as_ptr() as *const LogEvent)), 0); + if let Some(e) = LOGS.get_ptr_mut(&0) { let e = &mut *e; e.init_with_level(args.level); - e.info.etype = bpf_events::Type::Error; + e.info.etype = bpf_events::Type::Log; e.data.location.copy_from(&args.location); e.data.line = args.line; e.data.error = args.err; e.data.message = args.message; - bpf_events::pipe_error(ctx, e); + bpf_events::pipe_log(ctx, e); } } #[macro_export] -macro_rules! _error { +macro_rules! log { ($ctx:expr, $msg:literal, $err:expr, $level:expr) => {{ unsafe { const _PROBE_NAME: $crate::string::String<32> = $crate::probe_name!(); @@ -130,53 +129,44 @@ macro_rules! _error { level: $level, }; - $crate::errors::error_with_args($ctx, &args); + $crate::errors::log_with_args($ctx, &args); }; }}; } #[macro_export] macro_rules! error { - ($ctx:expr, $err:expr) => {{ - $crate::error!($ctx, "", $err) - }}; - - ($ctx:expr, $msg:literal, $err:expr) => {{ - $crate::_error!( - $ctx, - $msg, - Some($err), - $crate::bpf_events::error::Level::Error - ); - }}; -} - -#[macro_export] -macro_rules! error_msg { + // literal must be evaluated first ($ctx:expr, $msg:literal) => { - $crate::_error!($ctx, $msg, None, $crate::bpf_events::error::Level::Error) + $crate::log!($ctx, $msg, None, $crate::bpf_events::log::Level::Error) }; -} -#[macro_export] -macro_rules! warn { ($ctx:expr, $err:expr) => { - $crate::warn!($ctx, "", $err); + $crate::log!($ctx, "", Some($err), $crate::bpf_events::log::Level::Error) }; ($ctx:expr, $msg:literal, $err:expr) => { - $crate::_error!( + $crate::log!( $ctx, $msg, Some($err), - $crate::bpf_events::error::Level::Warn + $crate::bpf_events::log::Level::Error ); }; } #[macro_export] -macro_rules! warn_msg { +macro_rules! warn { + // literal must be evaluated first ($ctx:expr, $msg:literal) => { - $crate::_error!($ctx, $msg, None, $crate::bpf_events::error::Level::Warn) + $crate::log!($ctx, $msg, None, $crate::bpf_events::log::Level::Warn) + }; + + ($ctx:expr, $err:expr) => { + $crate::log!($ctx, "", Some($err), $crate::bpf_events::log::Level::Warn); + }; + + ($ctx:expr, $msg:literal, $err:expr) => { + $crate::log!($ctx, $msg, Some($err), $crate::bpf_events::log::Level::Warn); }; } diff --git a/kunai-ebpf/src/probes.rs b/kunai-ebpf/src/probes.rs index b90632d6..b42ceaaf 100644 --- a/kunai-ebpf/src/probes.rs +++ b/kunai-ebpf/src/probes.rs @@ -5,12 +5,12 @@ use kunai_common::{ bpf_events::*, co_re, consts::*, - error, error_msg, + error, errors::{self, *}, inspect_err, path::{self, *}, utils::*, - warn, warn_msg, + warn, }; #[cfg(feature = "debug")] diff --git a/kunai-ebpf/src/probes/bpf.rs b/kunai-ebpf/src/probes/bpf.rs index 623e2e7f..aecc65d9 100644 --- a/kunai-ebpf/src/probes/bpf.rs +++ b/kunai-ebpf/src/probes/bpf.rs @@ -72,7 +72,7 @@ unsafe fn try_bpf_prog_load(ctx: &RetProbeContext) -> ProbeResult<()> { if let Some(p_name) = bpf_prog_aux.name() { ignore_result!(inspect_err!( event.data.name.read_kernel_str_bytes(p_name), - |_| warn_msg!(ctx, "failed to read program name") + |_| warn!(ctx, "failed to read program name") )); } @@ -90,7 +90,7 @@ unsafe fn try_bpf_prog_load(ctx: &RetProbeContext) -> ProbeResult<()> { if let Some(afn) = bpf_prog_aux.attach_func_name() { ignore_result!(inspect_err!( event.data.attached_func_name.read_kernel_str_bytes(afn), - |_| warn_msg!(ctx, "failed to read attach_func_name") + |_| warn!(ctx, "failed to read attach_func_name") )); } @@ -102,7 +102,7 @@ unsafe fn try_bpf_prog_load(ctx: &RetProbeContext) -> ProbeResult<()> { pipe_event(ctx, event); } else { - error_msg!(ctx, "failed to retrieve BPF program load event") + error!(ctx, "failed to retrieve BPF program load event") } // we use a LruHashmap so we can safely ignore result diff --git a/kunai-ebpf/src/probes/bpf_socket.rs b/kunai-ebpf/src/probes/bpf_socket.rs index 633650e2..12f3fd62 100644 --- a/kunai-ebpf/src/probes/bpf_socket.rs +++ b/kunai-ebpf/src/probes/bpf_socket.rs @@ -122,7 +122,7 @@ unsafe fn handle_socket_attach_prog( } //handle loading of regular bpf program - warn_msg!(exit_ctx, "bpf program attached to socket not yet supported"); + warn!(exit_ctx, "bpf program attached to socket not yet supported"); Ok(()) } diff --git a/kunai-ebpf/src/probes/execve.rs b/kunai-ebpf/src/probes/execve.rs index 006f1a57..449432c0 100644 --- a/kunai-ebpf/src/probes/execve.rs +++ b/kunai-ebpf/src/probes/execve.rs @@ -131,7 +131,7 @@ unsafe fn execve_event(ctx: &C, rc: i32) -> ProbeResult<()> { .read_user_at(arg_start as *const u8, arg_len as u32) .is_err() { - warn_msg!(ctx, "failed to read argv") + warn!(ctx, "failed to read argv") } // cgroup parsing diff --git a/kunai-ebpf/src/probes/fs.rs b/kunai-ebpf/src/probes/fs.rs index ea1f7ead..b1a6125d 100644 --- a/kunai-ebpf/src/probes/fs.rs +++ b/kunai-ebpf/src/probes/fs.rs @@ -138,7 +138,7 @@ unsafe fn limit_eps_with_context(ctx: &C) -> ProbeResult { // we allow a process to take alone half of this otherwise we report it if let (true, limit) = is_task_io_limit_reach(task_limit) { if limit { - error_msg!(ctx, "current task i/o limit reached"); + error!(ctx, "current task i/o limit reached"); } return Ok(true); } @@ -146,7 +146,7 @@ unsafe fn limit_eps_with_context(ctx: &C) -> ProbeResult { // if there are too many I/O globally a random task can see its I/O ignored if let (true, limit) = is_global_io_limit_reach(glob_limit) { if limit { - error_msg!(ctx, "global i/o limit reached"); + error!(ctx, "global i/o limit reached"); } return Ok(true); } @@ -221,7 +221,7 @@ unsafe fn try_vfs_read(ctx: &ProbeContext) -> ProbeResult<()> { } // we mark file as being tracked - ignore_result!(inspect_err!(file_set_flag(&file, READ), |_| warn_msg!( + ignore_result!(inspect_err!(file_set_flag(&file, READ), |_| warn!( ctx, "failed to track file read" ))); @@ -297,7 +297,7 @@ unsafe fn try_vfs_write(ctx: &ProbeContext) -> ProbeResult<()> { } // we mark file as being tracked - ignore_result!(inspect_err!(file_set_flag(&file, WRITE), |_| warn_msg!( + ignore_result!(inspect_err!(file_set_flag(&file, WRITE), |_| warn!( ctx, "failed to track file write" ))); diff --git a/kunai-ebpf/src/probes/init_module.rs b/kunai-ebpf/src/probes/init_module.rs index 2c9d60cc..2f52d300 100644 --- a/kunai-ebpf/src/probes/init_module.rs +++ b/kunai-ebpf/src/probes/init_module.rs @@ -97,7 +97,7 @@ unsafe fn handle_init_module(ctx: &TracePointContext, args: InitModuleArgs) -> P .data .uargs .read_user_str_bytes(args.uargs() as *const u8), - |_| warn_msg!(ctx, "failed to read uargs") + |_| warn!(ctx, "failed to read uargs") )); // setting event data diff --git a/kunai-ebpf/src/probes/schedule.rs b/kunai-ebpf/src/probes/schedule.rs index ea2dc122..ba3715d1 100644 --- a/kunai-ebpf/src/probes/schedule.rs +++ b/kunai-ebpf/src/probes/schedule.rs @@ -97,7 +97,7 @@ unsafe fn try_schedule(ctx: &ProbeContext) -> ProbeResult<()> { // we do not really care if that is failing ignore_result!(inspect_err!(MARKED.insert(&task_uuid, &true, 0), |_| { - warn_msg!(ctx, "failed to track task") + warn!(ctx, "failed to track task") })); // we send event to userland diff --git a/kunai/src/bin/main.rs b/kunai/src/bin/main.rs index 631b5ddb..87ee1f33 100644 --- a/kunai/src/bin/main.rs +++ b/kunai/src/bin/main.rs @@ -27,7 +27,7 @@ use kunai::util::uname::Utsname; use kunai::yara::{Scanner, SourceCode}; use kunai::{cache, util}; use kunai_common::bpf_events::{ - self, error, event, mut_event, EncodedEvent, Event, PrctlOption, Signal, TaskInfo, Type, + self, event, mut_event, EncodedEvent, Event, PrctlOption, Signal, TaskInfo, Type, MAX_BPF_EVENT_SIZE, }; use kunai_common::config::Filter; @@ -2104,7 +2104,10 @@ impl EventConsumer<'_> { Err(e) => error!("failed to decode {} event: {:?}", etype, e), }, - Type::Error => panic!("error events should be processed earlier"), + Type::Log => { + #[cfg(debug_assertions)] + panic!("log events should be processed earlier") + } Type::SyscoreResume => { /* just ignore it */ } } } @@ -2295,11 +2298,12 @@ impl EventProducer { } } } - Type::Error => { - let e = event!(e, bpf_events::ErrorEvent).unwrap(); + Type::Log => { + let e = event!(e, bpf_events::LogEvent).unwrap(); match e.data.level { - error::Level::Warn => warn!("{}", e), - error::Level::Error => error!("{}", e), + bpf_events::log::Level::Info => info!("{}", e), + bpf_events::log::Level::Warn => warn!("{}", e), + bpf_events::log::Level::Error => error!("{}", e), } // we don't need to process such event further return true; @@ -2966,7 +2970,7 @@ impl Command { Type::Unknown | Type::CacheHash | Type::Correlation - | Type::Error + | Type::Log | Type::EndConfigurable | Type::TaskSched | Type::SyscoreResume From 7709467c2eff66a84065b9262f8d72517a221996 Mon Sep 17 00:00:00 2001 From: qjerome Date: Thu, 19 Dec 2024 15:54:57 +0100 Subject: [PATCH 2/2] doc: add comment --- kunai/src/bin/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kunai/src/bin/main.rs b/kunai/src/bin/main.rs index 87ee1f33..9ee566c7 100644 --- a/kunai/src/bin/main.rs +++ b/kunai/src/bin/main.rs @@ -2105,6 +2105,7 @@ impl EventConsumer<'_> { }, Type::Log => { + // only panic in debug #[cfg(debug_assertions)] panic!("log events should be processed earlier") }