diff --git a/aya/src/programs/kprobe.rs b/aya/src/programs/kprobe.rs index 53dac216..a61f084f 100644 --- a/aya/src/programs/kprobe.rs +++ b/aya/src/programs/kprobe.rs @@ -3,13 +3,14 @@ use std::{io, path::Path}; use thiserror::Error; use crate::{ - generated::bpf_prog_type::BPF_PROG_TYPE_KPROBE, + generated::{bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_KPROBE}, programs::{ define_link_wrapper, load_program, perf_attach::{PerfLinkIdInner, PerfLinkInner}, probe::{attach, ProbeKind}, - ProgramData, ProgramError, + FdLink, LinkError, ProgramData, ProgramError, }, + sys::bpf_link_get_info_by_fd, VerifierLogLevel, }; @@ -119,3 +120,32 @@ pub enum KProbeError { io_error: io::Error, }, } + +impl TryFrom for FdLink { + type Error = LinkError; + + fn try_from(value: KProbeLink) -> Result { + if let PerfLinkInner::FdLink(fd) = value.into_inner() { + Ok(fd) + } else { + Err(LinkError::InvalidLink) + } + } +} + +impl TryFrom for KProbeLink { + type Error = LinkError; + + fn try_from(fd_link: FdLink) -> Result { + let info = + bpf_link_get_info_by_fd(fd_link.fd).map_err(|io_error| LinkError::SyscallError { + call: "BPF_OBJ_GET_INFO_BY_FD", + code: 0, + io_error, + })?; + if info.type_ == (bpf_link_type::BPF_LINK_TYPE_KPROBE_MULTI as u32) { + return Ok(KProbeLink::new(PerfLinkInner::FdLink(fd_link))); + } + Err(LinkError::InvalidLink) + } +} diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index 3c245573..5de7eeef 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -6,6 +6,7 @@ pub use crate::generated::{ use crate::{ generated::{ + bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_PERF_EVENT, perf_type_id::{ PERF_TYPE_BREAKPOINT, PERF_TYPE_HARDWARE, PERF_TYPE_HW_CACHE, PERF_TYPE_RAW, @@ -16,9 +17,9 @@ use crate::{ links::define_link_wrapper, load_program, perf_attach, perf_attach::{PerfLinkIdInner, PerfLinkInner}, - ProgramData, ProgramError, + FdLink, LinkError, ProgramData, ProgramError, }, - sys::perf_event_open, + sys::{bpf_link_get_info_by_fd, perf_event_open}, }; /// The type of perf event @@ -189,6 +190,35 @@ impl PerfEvent { } } +impl TryFrom for FdLink { + type Error = LinkError; + + fn try_from(value: PerfEventLink) -> Result { + if let PerfLinkInner::FdLink(fd) = value.into_inner() { + Ok(fd) + } else { + Err(LinkError::InvalidLink) + } + } +} + +impl TryFrom for PerfEventLink { + type Error = LinkError; + + fn try_from(fd_link: FdLink) -> Result { + let info = + bpf_link_get_info_by_fd(fd_link.fd).map_err(|io_error| LinkError::SyscallError { + call: "BPF_OBJ_GET_INFO_BY_FD", + code: 0, + io_error, + })?; + if info.type_ == (bpf_link_type::BPF_LINK_TYPE_PERF_EVENT as u32) { + return Ok(PerfEventLink::new(PerfLinkInner::FdLink(fd_link))); + } + Err(LinkError::InvalidLink) + } +} + define_link_wrapper!( /// The link used by [PerfEvent] programs. PerfEventLink, diff --git a/aya/src/programs/trace_point.rs b/aya/src/programs/trace_point.rs index d67c6a41..b23594b7 100644 --- a/aya/src/programs/trace_point.rs +++ b/aya/src/programs/trace_point.rs @@ -3,14 +3,14 @@ use std::{fs, io, path::Path}; use thiserror::Error; use crate::{ - generated::bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT, + generated::{bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_TRACEPOINT}, programs::{ define_link_wrapper, load_program, perf_attach::{perf_attach, PerfLinkIdInner, PerfLinkInner}, utils::find_tracefs_path, - ProgramData, ProgramError, + FdLink, LinkError, ProgramData, ProgramError, }, - sys::perf_event_open_trace_point, + sys::{bpf_link_get_info_by_fd, perf_event_open_trace_point}, }; /// The type returned when attaching a [`TracePoint`] fails. @@ -116,6 +116,35 @@ define_link_wrapper!( PerfLinkIdInner ); +impl TryFrom for FdLink { + type Error = LinkError; + + fn try_from(value: TracePointLink) -> Result { + if let PerfLinkInner::FdLink(fd) = value.into_inner() { + Ok(fd) + } else { + Err(LinkError::InvalidLink) + } + } +} + +impl TryFrom for TracePointLink { + type Error = LinkError; + + fn try_from(fd_link: FdLink) -> Result { + let info = + bpf_link_get_info_by_fd(fd_link.fd).map_err(|io_error| LinkError::SyscallError { + call: "BPF_OBJ_GET_INFO_BY_FD", + code: 0, + io_error, + })?; + if info.type_ == (bpf_link_type::BPF_LINK_TYPE_TRACING as u32) { + return Ok(TracePointLink::new(PerfLinkInner::FdLink(fd_link))); + } + Err(LinkError::InvalidLink) + } +} + pub(crate) fn read_sys_fs_trace_point_id( tracefs: &Path, category: &str, diff --git a/aya/src/programs/uprobe.rs b/aya/src/programs/uprobe.rs index b632407e..bab82d4b 100644 --- a/aya/src/programs/uprobe.rs +++ b/aya/src/programs/uprobe.rs @@ -14,13 +14,14 @@ use std::{ use thiserror::Error; use crate::{ - generated::bpf_prog_type::BPF_PROG_TYPE_KPROBE, + generated::{bpf_link_type, bpf_prog_type::BPF_PROG_TYPE_KPROBE}, programs::{ define_link_wrapper, load_program, perf_attach::{PerfLinkIdInner, PerfLinkInner}, probe::{attach, ProbeKind}, - ProgramData, ProgramError, + FdLink, LinkError, ProgramData, ProgramError, }, + sys::bpf_link_get_info_by_fd, VerifierLogLevel, }; @@ -160,6 +161,35 @@ define_link_wrapper!( PerfLinkIdInner ); +impl TryFrom for FdLink { + type Error = LinkError; + + fn try_from(value: UProbeLink) -> Result { + if let PerfLinkInner::FdLink(fd) = value.into_inner() { + Ok(fd) + } else { + Err(LinkError::InvalidLink) + } + } +} + +impl TryFrom for UProbeLink { + type Error = LinkError; + + fn try_from(fd_link: FdLink) -> Result { + let info = + bpf_link_get_info_by_fd(fd_link.fd).map_err(|io_error| LinkError::SyscallError { + call: "BPF_OBJ_GET_INFO_BY_FD", + code: 0, + io_error, + })?; + if info.type_ == (bpf_link_type::BPF_LINK_TYPE_TRACING as u32) { + return Ok(UProbeLink::new(PerfLinkInner::FdLink(fd_link))); + } + Err(LinkError::InvalidLink) + } +} + /// The type returned when attaching an [`UProbe`] fails. #[derive(Debug, Error)] pub enum UProbeError {