diff --git a/crates/bpf-feature-autodetect/build.rs b/crates/bpf-feature-autodetect/build.rs index 7eee7713..c23521af 100644 --- a/crates/bpf-feature-autodetect/build.rs +++ b/crates/bpf-feature-autodetect/build.rs @@ -1,3 +1,5 @@ fn main() -> Result<(), Box> { - bpf_builder::build("test_lsm", "src/test_lsm.bpf.c") + bpf_builder::build("test_bpf_loop", "src/test_bpf_loop.bpf.c")?; + bpf_builder::build("test_lsm", "src/test_lsm.bpf.c")?; + Ok(()) } diff --git a/crates/bpf-feature-autodetect/src/bpf_loop.rs b/crates/bpf-feature-autodetect/src/bpf_loop.rs new file mode 100644 index 00000000..c67d0ddc --- /dev/null +++ b/crates/bpf-feature-autodetect/src/bpf_loop.rs @@ -0,0 +1,29 @@ +use aya::{include_bytes_aligned, programs::TracePoint, Bpf, BpfError}; +use log::warn; + +fn load_probe() -> Result<(), BpfError> { + let mut bpf = Bpf::load(include_bytes_aligned!(concat!( + env!("OUT_DIR"), + "/test_bpf_loop.none.bpf.o" + )))?; + let program: &mut TracePoint = bpf.program_mut("probe_bpf_loop").unwrap().try_into()?; + program.load()?; + Ok(()) +} + +pub fn bpf_loop_supported() -> bool { + match load_probe() { + Ok(_) => true, + Err(e) => { + let err_msg = "`bpf_loop` helper is not supported by the kernel"; + + if let Ok(true) = std::env::var("RUST_BACKTRACE").map(|s| s == "1") { + warn!("{err_msg}: {e}"); + } else { + warn!("{err_msg}"); + } + + false + } + } +} diff --git a/crates/bpf-feature-autodetect/src/lib.rs b/crates/bpf-feature-autodetect/src/lib.rs index ac6f0c77..db773547 100644 --- a/crates/bpf-feature-autodetect/src/lib.rs +++ b/crates/bpf-feature-autodetect/src/lib.rs @@ -10,12 +10,16 @@ use libc::SYS_bpf; use thiserror::Error; pub mod atomic; +pub mod bpf_loop; pub mod func; pub mod insn; pub mod kernel_version; pub mod lsm; -use crate::{atomic::atomics_supported, func::func_id_supported, lsm::lsm_supported}; +use crate::{ + atomic::atomics_supported, bpf_loop::bpf_loop_supported, func::func_id_supported, + lsm::lsm_supported, +}; /// Size of the eBPF verifier log. const LOG_SIZE: usize = 4096; @@ -34,12 +38,7 @@ pub fn autodetect_features() -> BpfFeatures { bpf_func_id::BPF_FUNC_get_current_task_btf, BpfProgType::BPF_PROG_TYPE_CGROUP_SKB, ), - bpf_loop: func_id_supported( - "bpf_loop", - bpf_func_id::BPF_FUNC_loop, - // Program type doesn't matter here. - BpfProgType::BPF_PROG_TYPE_KPROBE, - ), + bpf_loop: bpf_loop_supported(), lsm: lsm_supported(), } } diff --git a/crates/bpf-feature-autodetect/src/test_bpf_loop.bpf.c b/crates/bpf-feature-autodetect/src/test_bpf_loop.bpf.c new file mode 100644 index 00000000..c28a08f2 --- /dev/null +++ b/crates/bpf-feature-autodetect/src/test_bpf_loop.bpf.c @@ -0,0 +1,12 @@ +#include "vmlinux.h" +#include + +static int callback(void *ctx, u32 index) { + return 0; +} + +SEC("tracepoint") +int probe_bpf_loop(void *ctx) { + bpf_loop(5, callback, NULL, 0); + return 0; +}