diff --git a/aya/src/maps/mod.rs b/aya/src/maps/mod.rs index 849b14bc..21bb2b4c 100644 --- a/aya/src/maps/mod.rs +++ b/aya/src/maps/mod.rs @@ -60,9 +60,7 @@ use std::{ }; use aya_obj::{EbpfSectionKind, InvalidTypeBinding, generated::bpf_map_type, parse_map_info}; -use libc::{ - MAP_FAILED, RLIM_INFINITY, RLIMIT_MEMLOCK, c_int, c_void, getrlimit, off_t, rlim_t, rlimit, -}; +use libc::{RLIM_INFINITY, RLIMIT_MEMLOCK, getrlimit, rlim_t, rlimit}; use log::warn; use thiserror::Error; @@ -71,7 +69,7 @@ use crate::{ pin::PinError, sys::{ SyscallError, bpf_create_map, bpf_get_object, bpf_map_freeze, bpf_map_get_fd_by_id, - bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, mmap, munmap, + bpf_map_get_next_key, bpf_map_update_elem_ptr, bpf_pin_object, }, util::{KernelVersion, nr_cpus}, }; @@ -944,62 +942,6 @@ impl Deref for PerCpuValues { } } -// MMap corresponds to a memory-mapped region. -// -// The data is unmapped in Drop. -#[cfg_attr(test, derive(Debug))] -struct MMap { - ptr: ptr::NonNull, - len: usize, -} - -// Needed because NonNull is !Send and !Sync out of caution that the data -// might be aliased unsafely. -unsafe impl Send for MMap {} -unsafe impl Sync for MMap {} - -impl MMap { - fn new( - fd: BorrowedFd<'_>, - len: usize, - prot: c_int, - flags: c_int, - offset: off_t, - ) -> Result { - match unsafe { mmap(ptr::null_mut(), len, prot, flags, fd, offset) } { - MAP_FAILED => Err(SyscallError { - call: "mmap", - io_error: io::Error::last_os_error(), - }), - ptr => { - let ptr = ptr::NonNull::new(ptr).ok_or( - // This should never happen, but to be paranoid, and so we never need to talk - // about a null pointer, we check it anyway. - SyscallError { - call: "mmap", - io_error: io::Error::other("mmap returned null pointer"), - }, - )?; - Ok(Self { ptr, len }) - } - } - } -} - -impl AsRef<[u8]> for MMap { - fn as_ref(&self) -> &[u8] { - let Self { ptr, len } = self; - unsafe { std::slice::from_raw_parts(ptr.as_ptr().cast(), *len) } - } -} - -impl Drop for MMap { - fn drop(&mut self) { - let Self { ptr, len } = *self; - unsafe { munmap(ptr.as_ptr(), len) }; - } -} - #[cfg(test)] mod test_utils { use aya_obj::{ diff --git a/aya/src/maps/perf/perf_buffer.rs b/aya/src/maps/perf/perf_buffer.rs index 27554ac7..2b4a26a0 100644 --- a/aya/src/maps/perf/perf_buffer.rs +++ b/aya/src/maps/perf/perf_buffer.rs @@ -13,9 +13,8 @@ use bytes::BytesMut; use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use thiserror::Error; -use crate::{ - maps::MMap, - sys::{PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf}, +use crate::sys::{ + MMap, PerfEventIoctlRequest, SyscallError, perf_event_ioctl, perf_event_open_bpf, }; /// Perf buffer error. diff --git a/aya/src/maps/ring_buf.rs b/aya/src/maps/ring_buf.rs index e455329f..5c9bf3ae 100644 --- a/aya/src/maps/ring_buf.rs +++ b/aya/src/maps/ring_buf.rs @@ -17,7 +17,8 @@ use aya_obj::generated::{BPF_RINGBUF_BUSY_BIT, BPF_RINGBUF_DISCARD_BIT, BPF_RING use libc::{MAP_SHARED, PROT_READ, PROT_WRITE}; use crate::{ - maps::{MMap, MapData, MapError}, + maps::{MapData, MapError}, + sys::MMap, util::page_size, }; diff --git a/aya/src/sys/mmap.rs b/aya/src/sys/mmap.rs new file mode 100644 index 00000000..30ff0911 --- /dev/null +++ b/aya/src/sys/mmap.rs @@ -0,0 +1,63 @@ +//! Safe wrapper around memory-mapped files. + +use std::{io, os::fd::BorrowedFd, ptr}; + +use libc::{MAP_FAILED, c_int, c_void, off_t}; + +use super::{SyscallError, mmap, munmap}; + +// MMap corresponds to a memory-mapped region. +// +// The data is unmapped in Drop. +#[cfg_attr(test, derive(Debug))] +pub(crate) struct MMap { + pub(crate) ptr: ptr::NonNull, + pub(crate) len: usize, +} + +// Needed because NonNull is !Send and !Sync out of caution that the data +// might be aliased unsafely. +unsafe impl Send for MMap {} +unsafe impl Sync for MMap {} + +impl MMap { + pub(crate) fn new( + fd: BorrowedFd<'_>, + len: usize, + prot: c_int, + flags: c_int, + offset: off_t, + ) -> Result { + match unsafe { mmap(ptr::null_mut(), len, prot, flags, fd, offset) } { + MAP_FAILED => Err(SyscallError { + call: "mmap", + io_error: io::Error::last_os_error(), + }), + ptr => { + let ptr = ptr::NonNull::new(ptr).ok_or( + // This should never happen, but to be paranoid, and so we never need to talk + // about a null pointer, we check it anyway. + SyscallError { + call: "mmap", + io_error: io::Error::other("mmap returned null pointer"), + }, + )?; + Ok(Self { ptr, len }) + } + } + } +} + +impl AsRef<[u8]> for MMap { + fn as_ref(&self) -> &[u8] { + let Self { ptr, len } = self; + unsafe { std::slice::from_raw_parts(ptr.as_ptr().cast(), *len) } + } +} + +impl Drop for MMap { + fn drop(&mut self) { + let Self { ptr, len } = *self; + unsafe { munmap(ptr.as_ptr(), len) }; + } +} diff --git a/aya/src/sys/mod.rs b/aya/src/sys/mod.rs index f8c8944b..f1857ae1 100644 --- a/aya/src/sys/mod.rs +++ b/aya/src/sys/mod.rs @@ -1,6 +1,7 @@ //! A collection of system calls for performing eBPF related operations. mod bpf; +mod mmap; mod netlink; mod perf_event; @@ -17,6 +18,7 @@ use aya_obj::generated::{bpf_attr, bpf_cmd, perf_event_attr}; pub(crate) use bpf::*; #[cfg(test)] pub(crate) use fake::*; +pub(crate) use mmap::*; #[doc(hidden)] pub use netlink::netlink_set_link_up; pub(crate) use netlink::*;