From b20ad5c2437b3a7d0a8c7067f1d8b3190396afff Mon Sep 17 00:00:00 2001 From: Dave Tucker Date: Mon, 27 Jun 2022 22:20:10 +0100 Subject: [PATCH] aya: Add probe for bpf_link_create for perf programs Signed-off-by: Dave Tucker --- aya/src/bpf.rs | 6 +++++- aya/src/sys/bpf.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 9ac1e4df..86d476a5 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -31,7 +31,8 @@ use crate::{ bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, is_bpf_cookie_supported, is_btf_datasec_supported, is_btf_decl_tag_supported, is_btf_float_supported, is_btf_func_global_supported, is_btf_func_supported, is_btf_supported, - is_btf_type_tag_supported, is_prog_name_supported, retry_with_verifier_logs, + is_btf_type_tag_supported, is_perf_link_supported, is_prog_name_supported, + retry_with_verifier_logs, }, util::{bytes_of, possible_cpus, VerifierLog, POSSIBLE_CPUS}, }; @@ -125,6 +126,7 @@ lazy_static! { pub(crate) struct Features { pub bpf_name: bool, pub bpf_cookie: bool, + pub bpf_perf_link: bool, pub btf: bool, pub btf_func: bool, pub btf_func_global: bool, @@ -139,11 +141,13 @@ impl Features { let mut f = Features { bpf_name: is_prog_name_supported(), bpf_cookie: is_bpf_cookie_supported(), + bpf_perf_link: is_perf_link_supported(), btf: is_btf_supported(), ..Default::default() }; debug!("[FEAT PROBE] BPF program name support: {}", f.bpf_name); debug!("[FEAT PROBE] BPF cookie support: {}", f.bpf_cookie); + debug!("[FEAT PROBE] BPF probe link support: {}", f.bpf_perf_link); debug!("[FEAT PROBE] BTF support: {}", f.btf); if f.btf { diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index 1271251b..f60ba2cb 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -571,6 +571,37 @@ pub(crate) fn is_prog_name_supported() -> bool { } } +pub(crate) fn is_perf_link_supported() -> bool { + let mut attr = unsafe { mem::zeroed::() }; + let u = unsafe { &mut attr.__bindgen_anon_3 }; + + let prog: &[u8] = &[ + 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // mov64 r0 = 0 + 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit + ]; + + let gpl = b"GPL\0"; + u.license = gpl.as_ptr() as u64; + + let insns = copy_instructions(prog).unwrap(); + u.insn_cnt = insns.len() as u32; + u.insns = insns.as_ptr() as u64; + u.prog_type = bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT as u32; + + if let Ok(fd) = sys_bpf(bpf_cmd::BPF_PROG_LOAD, &attr) { + if let Err((code, _)) = + bpf_link_create(fd as i32, -1, bpf_attach_type::BPF_PERF_EVENT, None, 0) + { + if code == (-libc::EBADF).into() { + unsafe { libc::close(fd as i32) }; + return true; + } + unsafe { libc::close(fd as i32) }; + } + } + false +} + pub(crate) fn is_bpf_cookie_supported() -> bool { let mut attr = unsafe { mem::zeroed::() }; let u = unsafe { &mut attr.__bindgen_anon_3 };