diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index db1ad3be..e697ff05 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -28,10 +28,10 @@ use crate::{ SkSkbKind, SockOps, SocketFilter, TracePoint, UProbe, Xdp, }, sys::{ - bpf_load_btf, bpf_map_freeze, bpf_map_update_elem_ptr, 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, + 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, }, util::{bytes_of, possible_cpus, VerifierLog, POSSIBLE_CPUS}, }; @@ -120,6 +120,7 @@ impl Default for PinningType { #[derive(Default, Debug)] pub(crate) struct Features { pub bpf_name: bool, + pub bpf_cookie: bool, pub btf: bool, pub btf_func: bool, pub btf_func_global: bool, @@ -134,6 +135,9 @@ impl Features { self.bpf_name = is_prog_name_supported(); debug!("[FEAT PROBE] BPF program name support: {}", self.bpf_name); + self.bpf_cookie = is_bpf_cookie_supported(); + debug!("[FEAT PROBE] BPF cookie support: {}", self.bpf_cookie); + self.btf = is_btf_supported(); debug!("[FEAT PROBE] BTF support: {}", self.btf); diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index f408a49b..1271251b 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -571,6 +571,33 @@ pub(crate) fn is_prog_name_supported() -> bool { } } +pub(crate) fn is_bpf_cookie_supported() -> bool { + let mut attr = unsafe { mem::zeroed::() }; + let u = unsafe { &mut attr.__bindgen_anon_3 }; + + let prog: &[u8] = &[ + 0x85, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, // call bpf_get_attach_cookie + 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_KPROBE as u32; + + match sys_bpf(bpf_cmd::BPF_PROG_LOAD, &attr) { + Ok(v) => { + let fd = v as RawFd; + unsafe { close(fd) }; + true + } + Err(_) => false, + } +} + pub(crate) fn is_btf_supported() -> bool { let mut btf = Btf::new(); let name_offset = btf.add_string("int".to_string());