diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index e3dc4f99..3c7a0796 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -24,9 +24,10 @@ //! //! let intercept_egress = SockMap::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?; //! let map_fd = intercept_egress.fd()?; -//! let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; -//! prog.load()?; -//! prog.attach(map_fd)?; +//! // TODO (AM) figure out lifetimes +//! // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; +//! // prog.load()?; +//! // prog.attach(map_fd)?; //! //! # Ok::<(), aya::BpfError>(()) //! ``` diff --git a/aya/src/maps/perf/perf_buffer.rs b/aya/src/maps/perf/perf_buffer.rs index 8db3ee4d..283083d1 100644 --- a/aya/src/maps/perf/perf_buffer.rs +++ b/aya/src/maps/perf/perf_buffer.rs @@ -1,13 +1,16 @@ use std::{ ffi::c_void, io, mem, - os::unix::io::{AsRawFd, RawFd}, + os::{ + fd::OwnedFd, + unix::io::{AsRawFd, RawFd}, + }, ptr, slice, sync::atomic::{self, AtomicPtr, Ordering}, }; use bytes::BytesMut; -use libc::{c_int, close, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE}; +use libc::{c_int, munmap, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE}; use thiserror::Error; use crate::{ @@ -87,7 +90,7 @@ pub(crate) struct PerfBuffer { buf: AtomicPtr, size: usize, page_size: usize, - fd: RawFd, + fd: OwnedFd, } impl PerfBuffer { @@ -101,8 +104,7 @@ impl PerfBuffer { } let fd = perf_event_open_bpf(cpu_id as i32) - .map_err(|(_, io_error)| PerfBufferError::OpenError { io_error })? - as RawFd; + .map_err(|(_, io_error)| PerfBufferError::OpenError { io_error })?; let size = page_size * page_count; let buf = unsafe { mmap( @@ -110,7 +112,8 @@ impl PerfBuffer { size + page_size, PROT_READ | PROT_WRITE, MAP_SHARED, - fd, + // TODO (AM) + fd.as_raw_fd(), 0, ) }; @@ -127,7 +130,8 @@ impl PerfBuffer { page_size, }; - perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0) + // TODO (AM) + perf_event_ioctl(perf_buf.fd.as_raw_fd(), PERF_EVENT_IOC_ENABLE, 0) .map_err(|(_, io_error)| PerfBufferError::PerfEventEnableError { io_error })?; Ok(perf_buf) @@ -260,19 +264,19 @@ impl PerfBuffer { impl AsRawFd for PerfBuffer { fn as_raw_fd(&self) -> RawFd { - self.fd + self.fd.as_raw_fd() } } impl Drop for PerfBuffer { fn drop(&mut self) { unsafe { - let _ = perf_event_ioctl(self.fd, PERF_EVENT_IOC_DISABLE, 0); + // TODO (AM) + let _ = perf_event_ioctl(self.fd.as_raw_fd(), PERF_EVENT_IOC_DISABLE, 0); munmap( self.buf.load(Ordering::SeqCst) as *mut c_void, self.size + self.page_size, ); - close(self.fd); } } } diff --git a/aya/src/maps/sock/mod.rs b/aya/src/maps/sock/mod.rs index ffbf7aa3..e05359c1 100644 --- a/aya/src/maps/sock/mod.rs +++ b/aya/src/maps/sock/mod.rs @@ -5,14 +5,23 @@ mod sock_map; pub use sock_hash::SockHash; pub use sock_map::SockMap; -use std::os::unix::io::{AsRawFd, RawFd}; +use std::os::{ + fd::{AsFd, BorrowedFd}, + unix::io::{AsRawFd, RawFd}, +}; /// A socket map file descriptor. #[derive(Copy, Clone)] -pub struct SockMapFd(RawFd); +pub struct SockMapFd<'f>(BorrowedFd<'f>); -impl AsRawFd for SockMapFd { +impl AsRawFd for SockMapFd<'_> { fn as_raw_fd(&self) -> RawFd { - self.0 + self.0.as_raw_fd() + } +} + +impl AsFd for SockMapFd<'_> { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() } } diff --git a/aya/src/maps/sock/sock_hash.rs b/aya/src/maps/sock/sock_hash.rs index 89a49e9a..ec383ce1 100644 --- a/aya/src/maps/sock/sock_hash.rs +++ b/aya/src/maps/sock/sock_hash.rs @@ -49,9 +49,10 @@ use crate::{ /// let mut intercept_egress = SockHash::<_, u32>::try_from(bpf.map("INTERCEPT_EGRESS").unwrap())?; /// let map_fd = intercept_egress.fd()?; /// -/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; -/// prog.load()?; -/// prog.attach(map_fd)?; +/// // TODO (AM) : figure out lifetimes +/// // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; +/// // prog.load()?; +/// // prog.attach(map_fd)?; /// /// let mut client = TcpStream::connect("127.0.0.1:1234")?; /// let mut intercept_egress = SockHash::try_from(bpf.map_mut("INTERCEPT_EGRESS").unwrap())?; @@ -108,9 +109,8 @@ impl, K: Pod> SockHash { /// /// The returned file descriptor can be used to attach programs that work with /// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb). - pub fn fd(&self) -> Result { - // TODO (AM) - Ok(SockMapFd(self.inner.borrow().fd_or_err()?.as_raw_fd())) + pub fn fd(&self) -> Result, MapError> { + Ok(SockMapFd(self.inner.borrow().fd_or_err()?)) } } diff --git a/aya/src/maps/sock/sock_map.rs b/aya/src/maps/sock/sock_map.rs index ccc9e777..a82a9a5e 100644 --- a/aya/src/maps/sock/sock_map.rs +++ b/aya/src/maps/sock/sock_map.rs @@ -33,9 +33,10 @@ use crate::{ /// let intercept_ingress = SockMap::try_from(bpf.map("INTERCEPT_INGRESS").unwrap())?; /// let map_fd = intercept_ingress.fd()?; /// -/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; -/// prog.load()?; -/// prog.attach(map_fd)?; +/// // TODO (AM): figure out lifetimes +/// // let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; +/// // prog.load()?; +/// // prog.attach(map_fd)?; /// /// # Ok::<(), aya::BpfError>(()) /// ``` @@ -64,9 +65,8 @@ impl> SockMap { /// /// The returned file descriptor can be used to attach programs that work with /// socket maps, like [`SkMsg`](crate::programs::SkMsg) and [`SkSkb`](crate::programs::SkSkb). - pub fn fd(&self) -> Result { - // TODO (AM) - Ok(SockMapFd(self.inner.borrow().fd_or_err()?.as_raw_fd())) + pub fn fd(&self) -> Result, MapError> { + Ok(SockMapFd(self.inner.borrow().fd_or_err()?)) } } diff --git a/aya/src/programs/cgroup_device.rs b/aya/src/programs/cgroup_device.rs index 8b7d433f..f028ae95 100644 --- a/aya/src/programs/cgroup_device.rs +++ b/aya/src/programs/cgroup_device.rs @@ -1,5 +1,5 @@ //! Cgroup device programs. -use std::os::fd::AsRawFd; +use std::os::{fd::AsFd, unix::prelude::AsRawFd}; use crate::{ generated::{bpf_attach_type::BPF_CGROUP_DEVICE, bpf_prog_type::BPF_PROG_TYPE_CGROUP_DEVICE}, @@ -58,18 +58,19 @@ impl CgroupDevice { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [CgroupDevice::detach] - pub fn attach(&mut self, cgroup: T) -> Result { + pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); let k_ver = kernel_version().unwrap(); if k_ver >= (5, 7, 0) { - let link_fd = bpf_link_create(prog_fd, cgroup_fd, BPF_CGROUP_DEVICE, None, 0).map_err( - |(_, io_error)| ProgramError::SyscallError { - call: "bpf_link_create".to_owned(), - io_error, - }, - )?; + // TODO (AM) + let link_fd = + bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), BPF_CGROUP_DEVICE, None, 0) + .map_err(|(_, io_error)| ProgramError::SyscallError { + call: "bpf_link_create".to_owned(), + io_error, + })?; self.data .links .insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::Fd( @@ -86,7 +87,11 @@ impl CgroupDevice { .links .insert(CgroupDeviceLink::new(CgroupDeviceLinkInner::ProgAttach( // TODO (AM) - ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, BPF_CGROUP_DEVICE), + ProgAttachLink::new( + prog_fd.as_raw_fd(), + cgroup_fd.try_clone_to_owned()?, + BPF_CGROUP_DEVICE, + ), ))) } } diff --git a/aya/src/programs/cgroup_skb.rs b/aya/src/programs/cgroup_skb.rs index d59f252d..32c80319 100644 --- a/aya/src/programs/cgroup_skb.rs +++ b/aya/src/programs/cgroup_skb.rs @@ -1,5 +1,9 @@ //! Cgroup skb programs. -use std::{hash::Hash, os::fd::AsRawFd, path::Path}; +use std::{ + hash::Hash, + os::fd::{AsFd, AsRawFd}, + path::Path, +}; use crate::{ generated::{ @@ -80,13 +84,13 @@ impl CgroupSkb { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [CgroupSkb::detach]. - pub fn attach( + pub fn attach( &mut self, cgroup: T, attach_type: CgroupSkbAttachType, ) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); let attach_type = match attach_type { CgroupSkbAttachType::Ingress => BPF_CGROUP_INET_INGRESS, @@ -94,12 +98,12 @@ impl CgroupSkb { }; let k_ver = kernel_version().unwrap(); if k_ver >= (5, 7, 0) { - let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( - |(_, io_error)| ProgramError::SyscallError { + // TODO (AM) + let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0) + .map_err(|(_, io_error)| ProgramError::SyscallError { call: "bpf_link_create".to_owned(), io_error, - }, - )?; + })?; self.data .links .insert(CgroupSkbLink::new(CgroupSkbLinkInner::Fd(FdLink::new( @@ -117,7 +121,11 @@ impl CgroupSkb { .links .insert(CgroupSkbLink::new(CgroupSkbLinkInner::ProgAttach( // TODO (AM) - ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, attach_type), + ProgAttachLink::new( + prog_fd.as_raw_fd(), + cgroup_fd.try_clone_to_owned()?, + attach_type, + ), ))) } } diff --git a/aya/src/programs/cgroup_sock.rs b/aya/src/programs/cgroup_sock.rs index 24c72847..efb1486e 100644 --- a/aya/src/programs/cgroup_sock.rs +++ b/aya/src/programs/cgroup_sock.rs @@ -1,7 +1,11 @@ //! Cgroup socket programs. pub use aya_obj::programs::CgroupSockAttachType; -use std::{hash::Hash, os::fd::AsRawFd, path::Path}; +use std::{ + hash::Hash, + os::fd::{AsFd, AsRawFd}, + path::Path, +}; use crate::{ generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK, @@ -63,18 +67,18 @@ impl CgroupSock { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [CgroupSock::detach]. - pub fn attach(&mut self, cgroup: T) -> Result { + pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); let attach_type = self.data.expected_attach_type.unwrap(); let k_ver = kernel_version().unwrap(); if k_ver >= (5, 7, 0) { - let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( - |(_, io_error)| ProgramError::SyscallError { + // TODO (AM) + let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0) + .map_err(|(_, io_error)| ProgramError::SyscallError { call: "bpf_link_create".to_owned(), io_error, - }, - )?; + })?; self.data .links .insert(CgroupSockLink::new(CgroupSockLinkInner::Fd(FdLink::new( @@ -92,7 +96,11 @@ impl CgroupSock { .links .insert(CgroupSockLink::new(CgroupSockLinkInner::ProgAttach( // TODO (AM) - ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, attach_type), + ProgAttachLink::new( + prog_fd.as_raw_fd(), + cgroup_fd.try_clone_to_owned()?, + attach_type, + ), ))) } } diff --git a/aya/src/programs/cgroup_sock_addr.rs b/aya/src/programs/cgroup_sock_addr.rs index 07169300..6694026c 100644 --- a/aya/src/programs/cgroup_sock_addr.rs +++ b/aya/src/programs/cgroup_sock_addr.rs @@ -1,7 +1,11 @@ //! Cgroup socket address programs. pub use aya_obj::programs::CgroupSockAddrAttachType; -use std::{hash::Hash, os::fd::AsRawFd, path::Path}; +use std::{ + hash::Hash, + os::fd::{AsFd, AsRawFd}, + path::Path, +}; use crate::{ generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCK_ADDR, @@ -64,18 +68,17 @@ impl CgroupSockAddr { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [CgroupSockAddr::detach]. - pub fn attach(&mut self, cgroup: T) -> Result { + pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); let attach_type = self.data.expected_attach_type.unwrap(); let k_ver = kernel_version().unwrap(); if k_ver >= (5, 7, 0) { - let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( - |(_, io_error)| ProgramError::SyscallError { + let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0) + .map_err(|(_, io_error)| ProgramError::SyscallError { call: "bpf_link_create".to_owned(), io_error, - }, - )?; + })?; self.data .links .insert(CgroupSockAddrLink::new(CgroupSockAddrLinkInner::Fd( @@ -93,7 +96,7 @@ impl CgroupSockAddr { CgroupSockAddrLinkInner::ProgAttach(ProgAttachLink::new( // TODO (AM) prog_fd.as_raw_fd(), - cgroup_fd, + cgroup_fd.try_clone_to_owned()?, attach_type, )), )) diff --git a/aya/src/programs/cgroup_sockopt.rs b/aya/src/programs/cgroup_sockopt.rs index dcb7f3c2..adf9e4a0 100644 --- a/aya/src/programs/cgroup_sockopt.rs +++ b/aya/src/programs/cgroup_sockopt.rs @@ -1,7 +1,11 @@ //! Cgroup socket option programs. pub use aya_obj::programs::CgroupSockoptAttachType; -use std::{hash::Hash, os::fd::AsRawFd, path::Path}; +use std::{ + hash::Hash, + os::fd::{AsFd, AsRawFd}, + path::Path, +}; use crate::{ generated::bpf_prog_type::BPF_PROG_TYPE_CGROUP_SOCKOPT, @@ -61,18 +65,18 @@ impl CgroupSockopt { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [CgroupSockopt::detach]. - pub fn attach(&mut self, cgroup: T) -> Result { + pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); let attach_type = self.data.expected_attach_type.unwrap(); let k_ver = kernel_version().unwrap(); if k_ver >= (5, 7, 0) { - let link_fd = bpf_link_create(prog_fd, cgroup_fd, attach_type, None, 0).map_err( - |(_, io_error)| ProgramError::SyscallError { + // TODO (AM) + let link_fd = bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), attach_type, None, 0) + .map_err(|(_, io_error)| ProgramError::SyscallError { call: "bpf_link_create".to_owned(), io_error, - }, - )?; + })?; self.data .links .insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::Fd( @@ -90,7 +94,11 @@ impl CgroupSockopt { .links .insert(CgroupSockoptLink::new(CgroupSockoptLinkInner::ProgAttach( // TODO (AM) - ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, attach_type), + ProgAttachLink::new( + prog_fd.as_raw_fd(), + cgroup_fd.try_clone_to_owned()?, + attach_type, + ), ))) } } diff --git a/aya/src/programs/cgroup_sysctl.rs b/aya/src/programs/cgroup_sysctl.rs index e2f5d2e3..3ea314be 100644 --- a/aya/src/programs/cgroup_sysctl.rs +++ b/aya/src/programs/cgroup_sysctl.rs @@ -1,5 +1,8 @@ //! Cgroup sysctl programs. -use std::{hash::Hash, os::fd::AsRawFd}; +use std::{ + hash::Hash, + os::fd::{AsFd, AsRawFd}, +}; use crate::{ generated::{bpf_attach_type::BPF_CGROUP_SYSCTL, bpf_prog_type::BPF_PROG_TYPE_CGROUP_SYSCTL}, @@ -57,18 +60,19 @@ impl CgroupSysctl { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [CgroupSysctl::detach]. - pub fn attach(&mut self, cgroup: T) -> Result { + pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); let k_ver = kernel_version().unwrap(); if k_ver >= (5, 7, 0) { - let link_fd = bpf_link_create(prog_fd, cgroup_fd, BPF_CGROUP_SYSCTL, None, 0).map_err( - |(_, io_error)| ProgramError::SyscallError { - call: "bpf_link_create".to_owned(), - io_error, - }, - )?; + // TODO (AM) + let link_fd = + bpf_link_create(prog_fd, cgroup_fd.as_raw_fd(), BPF_CGROUP_SYSCTL, None, 0) + .map_err(|(_, io_error)| ProgramError::SyscallError { + call: "bpf_link_create".to_owned(), + io_error, + })?; self.data .links .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::Fd( @@ -86,7 +90,11 @@ impl CgroupSysctl { .links .insert(CgroupSysctlLink::new(CgroupSysctlLinkInner::ProgAttach( // TODO (AM) - ProgAttachLink::new(prog_fd.as_raw_fd(), cgroup_fd, BPF_CGROUP_SYSCTL), + ProgAttachLink::new( + prog_fd.as_raw_fd(), + cgroup_fd.try_clone_to_owned()?, + BPF_CGROUP_SYSCTL, + ), ))) } } diff --git a/aya/src/programs/links.rs b/aya/src/programs/links.rs index 88149205..ecf25dfb 100644 --- a/aya/src/programs/links.rs +++ b/aya/src/programs/links.rs @@ -1,5 +1,4 @@ //! Program links. -use libc::{close, dup}; use thiserror::Error; use std::{ @@ -208,19 +207,19 @@ pub struct ProgAttachLinkId(RawFd, RawFd, bpf_attach_type); #[derive(Debug)] pub struct ProgAttachLink { prog_fd: RawFd, - target_fd: RawFd, + target_fd: OwnedFd, attach_type: bpf_attach_type, } impl ProgAttachLink { pub(crate) fn new( prog_fd: RawFd, - target_fd: RawFd, + target_fd: OwnedFd, attach_type: bpf_attach_type, ) -> ProgAttachLink { ProgAttachLink { prog_fd, - target_fd: unsafe { dup(target_fd) }, + target_fd, attach_type, } } @@ -230,12 +229,13 @@ impl Link for ProgAttachLink { type Id = ProgAttachLinkId; fn id(&self) -> Self::Id { - ProgAttachLinkId(self.prog_fd, self.target_fd, self.attach_type) + // TODO (AM) + ProgAttachLinkId(self.prog_fd, self.target_fd.as_raw_fd(), self.attach_type) } fn detach(self) -> Result<(), ProgramError> { - let _ = bpf_prog_detach(self.prog_fd, self.target_fd, self.attach_type); - unsafe { close(self.target_fd) }; + // TODO (AM) + let _ = bpf_prog_detach(self.prog_fd, self.target_fd.as_raw_fd(), self.attach_type); Ok(()) } } diff --git a/aya/src/programs/lirc_mode2.rs b/aya/src/programs/lirc_mode2.rs index 960f3f93..0eff664c 100644 --- a/aya/src/programs/lirc_mode2.rs +++ b/aya/src/programs/lirc_mode2.rs @@ -1,5 +1,5 @@ //! Lirc programs. -use std::os::fd::{AsRawFd, RawFd}; +use std::os::fd::{AsFd, AsRawFd, OwnedFd, RawFd}; use crate::{ generated::{bpf_attach_type::BPF_LIRC_MODE2, bpf_prog_type::BPF_PROG_TYPE_LIRC_MODE2}, @@ -7,8 +7,6 @@ use crate::{ sys::{bpf_prog_attach, bpf_prog_detach, bpf_prog_get_fd_by_id, bpf_prog_get_info_by_fd}, }; -use libc::{close, dup}; - /// A program used to decode IR into key events for a lirc device. /// /// [`LircMode2`] programs can be used to inspect infrared pulses, spaces, @@ -60,9 +58,9 @@ impl LircMode2 { /// Attaches the program to the given lirc device. /// /// The returned value can be used to detach, see [LircMode2::detach]. - pub fn attach(&mut self, lircdev: T) -> Result { + pub fn attach(&mut self, lircdev: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let lircdev_fd = lircdev.as_raw_fd(); + let lircdev_fd = lircdev.as_fd(); bpf_prog_attach(prog_fd, lircdev_fd, BPF_LIRC_MODE2).map_err(|(_, io_error)| { ProgramError::SyscallError { @@ -72,9 +70,10 @@ impl LircMode2 { })?; // TODO (AM) - self.data - .links - .insert(LircLink::new(prog_fd.as_raw_fd(), lircdev_fd)) + self.data.links.insert(LircLink::new( + prog_fd.as_raw_fd(), + lircdev_fd.try_clone_to_owned()?, + )) } /// Detaches the program. @@ -93,8 +92,9 @@ impl LircMode2 { } /// Queries the lirc device for attached programs. - pub fn query(target_fd: T) -> Result, ProgramError> { - let prog_ids = query(target_fd.as_raw_fd(), BPF_LIRC_MODE2, 0, &mut None)?; + pub fn query(target_fd: T) -> Result, ProgramError> { + let target_fd = target_fd.as_fd(); + let prog_ids = query(target_fd, BPF_LIRC_MODE2, 0, &mut None)?; let mut prog_fds = Vec::with_capacity(prog_ids.len()); @@ -107,10 +107,10 @@ impl LircMode2 { prog_fds.push(fd as RawFd); } - Ok(prog_fds + prog_fds .into_iter() - .map(|prog_fd| LircLink::new(prog_fd, target_fd.as_raw_fd())) - .collect()) + .map(|prog_fd| Ok(LircLink::new(prog_fd, target_fd.try_clone_to_owned()?))) + .collect() } } @@ -122,15 +122,12 @@ pub struct LircLinkId(RawFd, RawFd); /// An LircMode2 Link pub struct LircLink { prog_fd: RawFd, - target_fd: RawFd, + target_fd: OwnedFd, } impl LircLink { - pub(crate) fn new(prog_fd: RawFd, target_fd: RawFd) -> LircLink { - LircLink { - prog_fd, - target_fd: unsafe { dup(target_fd) }, - } + pub(crate) fn new(prog_fd: RawFd, target_fd: OwnedFd) -> LircLink { + LircLink { prog_fd, target_fd } } /// Get ProgramInfo from this link @@ -149,12 +146,13 @@ impl Link for LircLink { type Id = LircLinkId; fn id(&self) -> Self::Id { - LircLinkId(self.prog_fd, self.target_fd) + // TODO (AM) + LircLinkId(self.prog_fd, self.target_fd.as_raw_fd()) } fn detach(self) -> Result<(), ProgramError> { - let _ = bpf_prog_detach(self.prog_fd, self.target_fd, BPF_LIRC_MODE2); - unsafe { close(self.target_fd) }; + // TODO (AM) + let _ = bpf_prog_detach(self.prog_fd, self.target_fd.as_raw_fd(), BPF_LIRC_MODE2); Ok(()) } } diff --git a/aya/src/programs/perf_attach.rs b/aya/src/programs/perf_attach.rs index 0746b12a..e62d8d6a 100644 --- a/aya/src/programs/perf_attach.rs +++ b/aya/src/programs/perf_attach.rs @@ -1,7 +1,6 @@ //! Perf attach links. -use libc::close; use std::os::{ - fd::{AsRawFd, BorrowedFd}, + fd::{AsRawFd, BorrowedFd, OwnedFd}, unix::io::RawFd, }; @@ -49,7 +48,7 @@ pub struct PerfLinkId(RawFd); /// The attachment type of PerfEvent programs. #[derive(Debug)] pub struct PerfLink { - perf_fd: RawFd, + perf_fd: OwnedFd, probe_kind: Option, event_alias: Option, } @@ -58,12 +57,13 @@ impl Link for PerfLink { type Id = PerfLinkId; fn id(&self) -> Self::Id { - PerfLinkId(self.perf_fd) + // TODO (AM) + PerfLinkId(self.perf_fd.as_raw_fd()) } fn detach(mut self) -> Result<(), ProgramError> { - let _ = perf_event_ioctl(self.perf_fd, PERF_EVENT_IOC_DISABLE, 0); - unsafe { close(self.perf_fd) }; + // TODO (AM) + let _ = perf_event_ioctl(self.perf_fd.as_raw_fd(), PERF_EVENT_IOC_DISABLE, 0); if let Some(probe_kind) = self.probe_kind.take() { if let Some(event_alias) = self.event_alias.take() { @@ -77,16 +77,15 @@ impl Link for PerfLink { pub(crate) fn perf_attach( prog_fd: BorrowedFd<'_>, - fd: RawFd, + fd: OwnedFd, ) -> Result { if FEATURES.bpf_perf_link() { - let link_fd = - bpf_link_create(prog_fd, fd, BPF_PERF_EVENT, None, 0).map_err(|(_, io_error)| { - ProgramError::SyscallError { - call: "bpf_link_create".to_owned(), - io_error, - } - })?; + let link_fd = bpf_link_create(prog_fd, fd.as_raw_fd(), BPF_PERF_EVENT, None, 0).map_err( + |(_, io_error)| ProgramError::SyscallError { + call: "bpf_link_create".to_owned(), + io_error, + }, + )?; Ok(PerfLinkInner::FdLink(FdLink::new(link_fd))) } else { perf_attach_either(prog_fd, fd, None, None) @@ -95,7 +94,7 @@ pub(crate) fn perf_attach( pub(crate) fn perf_attach_debugfs( prog_fd: BorrowedFd<'_>, - fd: RawFd, + fd: OwnedFd, probe_kind: ProbeKind, event_alias: String, ) -> Result { @@ -104,17 +103,19 @@ pub(crate) fn perf_attach_debugfs( fn perf_attach_either( prog_fd: BorrowedFd<'_>, - fd: RawFd, + fd: OwnedFd, probe_kind: Option, event_alias: Option, ) -> Result { - perf_event_ioctl(fd, PERF_EVENT_IOC_SET_BPF, prog_fd.as_raw_fd()).map_err( + // TODO (AM) + perf_event_ioctl(fd.as_raw_fd(), PERF_EVENT_IOC_SET_BPF, prog_fd.as_raw_fd()).map_err( |(_, io_error)| ProgramError::SyscallError { call: "PERF_EVENT_IOC_SET_BPF".to_owned(), io_error, }, )?; - perf_event_ioctl(fd, PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| { + // TODO (AM) + perf_event_ioctl(fd.as_raw_fd(), PERF_EVENT_IOC_ENABLE, 0).map_err(|(_, io_error)| { ProgramError::SyscallError { call: "PERF_EVENT_IOC_ENABLE".to_owned(), io_error, diff --git a/aya/src/programs/perf_event.rs b/aya/src/programs/perf_event.rs index 177b3544..576a34ed 100644 --- a/aya/src/programs/perf_event.rs +++ b/aya/src/programs/perf_event.rs @@ -167,7 +167,7 @@ impl PerfEvent { .map_err(|(_code, io_error)| ProgramError::SyscallError { call: "perf_event_open".to_owned(), io_error, - })? as i32; + })?; let link = perf_attach(self.data.fd_or_err()?, fd)?; self.data.links.insert(PerfEventLink::new(link)) diff --git a/aya/src/programs/probe.rs b/aya/src/programs/probe.rs index 4ecf80a5..bd356b5a 100644 --- a/aya/src/programs/probe.rs +++ b/aya/src/programs/probe.rs @@ -2,6 +2,7 @@ use libc::pid_t; use std::{ fs::{self, OpenOptions}, io::{self, Write}, + os::fd::OwnedFd, path::Path, process, sync::atomic::{AtomicUsize, Ordering}, @@ -86,7 +87,7 @@ fn create_as_probe( fn_name: &str, offset: u64, pid: Option, -) -> Result { +) -> Result { use ProbeKind::*; let perf_ty = match kind { @@ -113,7 +114,7 @@ fn create_as_probe( call: "perf_event_open".to_owned(), io_error, }, - )? as i32; + )?; Ok(fd) } @@ -123,7 +124,7 @@ fn create_as_trace_point( name: &str, offset: u64, pid: Option, -) -> Result<(i32, String), ProgramError> { +) -> Result<(OwnedFd, String), ProgramError> { use ProbeKind::*; let tracefs = find_tracefs_path()?; @@ -142,7 +143,7 @@ fn create_as_trace_point( call: "perf_event_open".to_owned(), io_error, } - })? as i32; + })?; Ok((fd, event_alias)) } diff --git a/aya/src/programs/sk_msg.rs b/aya/src/programs/sk_msg.rs index 4c18c93e..88e61cf2 100644 --- a/aya/src/programs/sk_msg.rs +++ b/aya/src/programs/sk_msg.rs @@ -1,6 +1,6 @@ //! Skmsg programs. -use std::os::unix::io::AsRawFd; +use std::os::{fd::AsFd, unix::io::AsRawFd}; use crate::{ generated::{bpf_attach_type::BPF_SK_MSG_VERDICT, bpf_prog_type::BPF_PROG_TYPE_SK_MSG}, @@ -46,9 +46,10 @@ use crate::{ /// let intercept_egress: SockHash<_, u32> = bpf.map("INTERCEPT_EGRESS").unwrap().try_into()?; /// let map_fd = intercept_egress.fd()?; /// -/// let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; -/// prog.load()?; -/// prog.attach(map_fd)?; +/// // TODO (AM): Figure out lifetimes +/// // let prog: &mut SkMsg = bpf.program_mut("intercept_egress_packet").unwrap().try_into()?; +/// // prog.load()?; +/// // prog.attach(map_fd)?; /// /// let mut client = TcpStream::connect("127.0.0.1:1234")?; /// let mut intercept_egress: SockHash<_, u32> = bpf.map_mut("INTERCEPT_EGRESS").unwrap().try_into()?; @@ -78,9 +79,9 @@ impl SkMsg { /// Attaches the program to the given sockmap. /// /// The returned value can be used to detach, see [SkMsg::detach]. - pub fn attach(&mut self, map: SockMapFd) -> Result { + pub fn attach(&mut self, map: SockMapFd<'_>) -> Result { let prog_fd = self.data.fd_or_err()?; - let map_fd = map.as_raw_fd(); + let map_fd = map.as_fd(); bpf_prog_attach(prog_fd, map_fd, BPF_SK_MSG_VERDICT).map_err(|(_, io_error)| { ProgramError::SyscallError { @@ -91,7 +92,7 @@ impl SkMsg { self.data.links.insert(SkMsgLink::new(ProgAttachLink::new( // TODO (AM) prog_fd.as_raw_fd(), - map_fd, + map_fd.try_clone_to_owned()?, BPF_SK_MSG_VERDICT, ))) } diff --git a/aya/src/programs/sk_skb.rs b/aya/src/programs/sk_skb.rs index fd354fca..65d0f5cb 100644 --- a/aya/src/programs/sk_skb.rs +++ b/aya/src/programs/sk_skb.rs @@ -1,6 +1,9 @@ //! Skskb programs. -use std::{os::unix::io::AsRawFd, path::Path}; +use std::{ + os::{fd::AsFd, unix::io::AsRawFd}, + path::Path, +}; use crate::{ generated::{ @@ -44,9 +47,10 @@ pub enum SkSkbKind { /// let intercept_ingress: SockMap<_> = bpf.map("INTERCEPT_INGRESS").unwrap().try_into()?; /// let map_fd = intercept_ingress.fd()?; /// -/// let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; -/// prog.load()?; -/// prog.attach(map_fd)?; +/// // TODO (AM): figure out lifetimes +/// // let prog: &mut SkSkb = bpf.program_mut("intercept_ingress_packet").unwrap().try_into()?; +/// // prog.load()?; +/// // prog.attach(map_fd)?; /// /// # Ok::<(), aya::BpfError>(()) /// ``` @@ -70,9 +74,9 @@ impl SkSkb { /// Attaches the program to the given socket map. /// /// The returned value can be used to detach, see [SkSkb::detach]. - pub fn attach(&mut self, map: SockMapFd) -> Result { + pub fn attach(&mut self, map: SockMapFd<'_>) -> Result { let prog_fd = self.data.fd_or_err()?; - let map_fd = map.as_raw_fd(); + let map_fd = map.as_fd(); let attach_type = match self.kind { SkSkbKind::StreamParser => BPF_SK_SKB_STREAM_PARSER, @@ -87,7 +91,7 @@ impl SkSkb { // TODO (AM) self.data.links.insert(SkSkbLink::new(ProgAttachLink::new( prog_fd.as_raw_fd(), - map_fd, + map_fd.try_clone_to_owned()?, attach_type, ))) } diff --git a/aya/src/programs/sock_ops.rs b/aya/src/programs/sock_ops.rs index db4f7f30..eab2c876 100644 --- a/aya/src/programs/sock_ops.rs +++ b/aya/src/programs/sock_ops.rs @@ -1,5 +1,5 @@ //! Socket option programs. -use std::os::unix::io::AsRawFd; +use std::os::{fd::AsFd, unix::io::AsRawFd}; use crate::{ generated::{bpf_attach_type::BPF_CGROUP_SOCK_OPS, bpf_prog_type::BPF_PROG_TYPE_SOCK_OPS}, @@ -58,9 +58,9 @@ impl SockOps { /// Attaches the program to the given cgroup. /// /// The returned value can be used to detach, see [SockOps::detach]. - pub fn attach(&mut self, cgroup: T) -> Result { + pub fn attach(&mut self, cgroup: T) -> Result { let prog_fd = self.data.fd_or_err()?; - let cgroup_fd = cgroup.as_raw_fd(); + let cgroup_fd = cgroup.as_fd(); bpf_prog_attach(prog_fd, cgroup_fd, BPF_CGROUP_SOCK_OPS).map_err(|(_, io_error)| { ProgramError::SyscallError { @@ -71,7 +71,7 @@ impl SockOps { // TODO (AM) self.data.links.insert(SockOpsLink::new(ProgAttachLink::new( prog_fd.as_raw_fd(), - cgroup_fd, + cgroup_fd.try_clone_to_owned()?, BPF_CGROUP_SOCK_OPS, ))) } diff --git a/aya/src/programs/trace_point.rs b/aya/src/programs/trace_point.rs index f43cd77e..72991aaa 100644 --- a/aya/src/programs/trace_point.rs +++ b/aya/src/programs/trace_point.rs @@ -85,7 +85,7 @@ impl TracePoint { call: "perf_event_open".to_owned(), io_error, } - })? as i32; + })?; let link = perf_attach(self.data.fd_or_err()?, fd)?; self.data.links.insert(TracePointLink::new(link)) diff --git a/aya/src/sys/bpf.rs b/aya/src/sys/bpf.rs index 48ba4578..f31ce6fa 100644 --- a/aya/src/sys/bpf.rs +++ b/aya/src/sys/bpf.rs @@ -421,13 +421,13 @@ pub(crate) fn bpf_link_update( pub(crate) fn bpf_prog_attach( prog_fd: BorrowedFd<'_>, - target_fd: RawFd, + target_fd: BorrowedFd<'_>, attach_type: bpf_attach_type, ) -> SysResult { let mut attr = unsafe { mem::zeroed::() }; attr.__bindgen_anon_5.attach_bpf_fd = prog_fd.as_raw_fd() as u32; - attr.__bindgen_anon_5.target_fd = target_fd as u32; + attr.__bindgen_anon_5.target_fd = target_fd.as_raw_fd() as u32; attr.__bindgen_anon_5.attach_type = attach_type as u32; sys_bpf(bpf_cmd::BPF_PROG_ATTACH, &attr) diff --git a/aya/src/sys/perf_event.rs b/aya/src/sys/perf_event.rs index 68eddd35..53764f10 100644 --- a/aya/src/sys/perf_event.rs +++ b/aya/src/sys/perf_event.rs @@ -1,4 +1,8 @@ -use std::{ffi::CString, mem}; +use std::{ + ffi::CString, + io, mem, + os::fd::{FromRawFd, OwnedFd, RawFd}, +}; use libc::{c_int, pid_t}; @@ -12,6 +16,8 @@ use crate::generated::{ use super::{syscall, SysResult, Syscall}; +type Result = std::result::Result; + #[allow(clippy::too_many_arguments)] pub(crate) fn perf_event_open( perf_type: u32, @@ -22,7 +28,7 @@ pub(crate) fn perf_event_open( sample_frequency: Option, wakeup: bool, flags: u32, -) -> SysResult { +) -> Result { let mut attr = unsafe { mem::zeroed::() }; attr.config = config; @@ -39,16 +45,19 @@ pub(crate) fn perf_event_open( attr.__bindgen_anon_1.sample_period = sample_period; } - syscall(Syscall::PerfEventOpen { + let fd = syscall(Syscall::PerfEventOpen { attr, pid, cpu, group: -1, flags, - }) + })? as RawFd; + + // SAFETY: perf_event_open returns new fd + Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } -pub(crate) fn perf_event_open_bpf(cpu: c_int) -> SysResult { +pub(crate) fn perf_event_open_bpf(cpu: c_int) -> Result { perf_event_open( PERF_TYPE_SOFTWARE as u32, PERF_COUNT_SW_BPF_OUTPUT as u64, @@ -67,7 +76,7 @@ pub(crate) fn perf_event_open_probe( name: &str, offset: u64, pid: Option, -) -> SysResult { +) -> Result { let mut attr = unsafe { mem::zeroed::() }; if let Some(ret_bit) = ret_bit { @@ -84,16 +93,19 @@ pub(crate) fn perf_event_open_probe( let cpu = if pid.is_some() { -1 } else { 0 }; let pid = pid.unwrap_or(-1); - syscall(Syscall::PerfEventOpen { + let fd = syscall(Syscall::PerfEventOpen { attr, pid, cpu, group: -1, flags: PERF_FLAG_FD_CLOEXEC, - }) + })? as RawFd; + + // SAFETY: perf_event_open returns new fd + Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } -pub(crate) fn perf_event_open_trace_point(id: u32, pid: Option) -> SysResult { +pub(crate) fn perf_event_open_trace_point(id: u32, pid: Option) -> Result { let mut attr = unsafe { mem::zeroed::() }; attr.size = mem::size_of::() as u32; @@ -103,13 +115,15 @@ pub(crate) fn perf_event_open_trace_point(id: u32, pid: Option) -> SysRes let cpu = if pid.is_some() { -1 } else { 0 }; let pid = pid.unwrap_or(-1); - syscall(Syscall::PerfEventOpen { + let fd = syscall(Syscall::PerfEventOpen { attr, pid, cpu, group: -1, flags: PERF_FLAG_FD_CLOEXEC, - }) + })? as RawFd; + // SAFETY: perf_event_open returns new fd + Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } pub(crate) fn perf_event_ioctl(fd: c_int, request: c_int, arg: c_int) -> SysResult { diff --git a/test/integration-ebpf/src/bpf_probe_read.rs b/test/integration-ebpf/src/bpf_probe_read.rs index fcabede0..1ee8878c 100644 --- a/test/integration-ebpf/src/bpf_probe_read.rs +++ b/test/integration-ebpf/src/bpf_probe_read.rs @@ -14,8 +14,8 @@ macro_rules! read_str_bytes { ($fun:ident, $ptr:expr, $len:expr $(,)?) => { let r = unsafe { let Some(ptr) = RESULT.get_ptr_mut(0) else { - return; - }; + return; + }; &mut *ptr };