aya: uprobe attach: use mmap instead of reading whole binaries to memory

reviewable/pr1264/r8
Omri Steiner 2 weeks ago committed by Tamir Duberstein
parent 647100faa7
commit 90d5604877

@ -24,6 +24,7 @@ use crate::{
probe::{OsStringExt as _, ProbeKind, attach},
},
sys::bpf_link_get_info_by_fd,
util::MMap,
};
const LD_SO_CACHE_FILE: &str = "/etc/ld.so.cache";
@ -686,15 +687,15 @@ fn find_symbol_in_object<'a>(obj: &'a object::File<'a>, symbol: &str) -> Option<
}
fn resolve_symbol(path: &Path, symbol: &str) -> Result<u64, ResolveSymbolError> {
let data = fs::read(path)?;
let obj = object::read::File::parse(&*data)?;
let data = MMap::map_copy_read_only(path)?;
let obj = object::read::File::parse(data.as_ref())?;
if let Some(sym) = find_symbol_in_object(&obj, symbol) {
symbol_translated_address(&obj, sym, symbol)
} else {
// Only search in the debug object if the symbol was not found in the main object
let debug_path = find_debug_path_in_object(&obj, path, symbol)?;
let debug_data = fs::read(&debug_path).map_err(|e| {
let debug_data = MMap::map_copy_read_only(&debug_path).map_err(|e| {
ResolveSymbolError::DebuglinkAccessError(
debug_path
.to_str()
@ -703,7 +704,7 @@ fn resolve_symbol(path: &Path, symbol: &str) -> Result<u64, ResolveSymbolError>
e,
)
})?;
let debug_obj = object::read::File::parse(&*debug_data)?;
let debug_obj = object::read::File::parse(debug_data.as_ref())?;
verify_build_ids(&obj, &debug_obj, symbol)?;

@ -8,14 +8,16 @@ use std::{
io::{self, BufRead, BufReader},
mem,
num::ParseIntError,
os::fd::BorrowedFd,
os::fd::{AsFd as _, BorrowedFd},
path::Path,
ptr, slice,
str::{FromStr, Utf8Error},
};
use aya_obj::generated::{TC_H_MAJ_MASK, TC_H_MIN_MASK};
use libc::{
_SC_PAGESIZE, MAP_FAILED, c_int, c_void, if_nametoindex, off_t, sysconf, uname, utsname,
_SC_PAGESIZE, MAP_FAILED, MAP_PRIVATE, PROT_READ, c_int, c_void, if_nametoindex, off_t,
sysconf, uname, utsname,
};
use log::warn;
@ -478,6 +480,24 @@ impl MMap {
}
}
/// Maps the file at `path` for reading, using `mmap` with `MAP_PRIVATE`.
pub(crate) fn map_copy_read_only(path: &Path) -> Result<Self, io::Error> {
let file = fs::File::open(path)?;
Self::new(
file.as_fd(),
file.metadata()?.len().try_into().map_err(|e| {
io::Error::new(
io::ErrorKind::FileTooLarge,
format!("file too large to mmap: {e}"),
)
})?,
PROT_READ,
MAP_PRIVATE,
0,
)
.map_err(|SyscallError { io_error, call: _ }| io_error)
}
pub(crate) fn ptr(&self) -> ptr::NonNull<c_void> {
self.ptr
}

Loading…
Cancel
Save