Merge pull request #717 from ajwerner/no-libc-in-integration-tests

uprobe,integration-test: do not exercise dylib resolution in integration tests
reviewable/pr638/r15
ajwerner 1 year ago committed by GitHub
commit de8604d011
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -82,36 +82,7 @@ impl UProbe {
target: T, target: T,
pid: Option<pid_t>, pid: Option<pid_t>,
) -> Result<UProbeLinkId, ProgramError> { ) -> Result<UProbeLinkId, ProgramError> {
let target = target.as_ref(); let path = resolve_attach_path(target, pid)?;
let target_str = &*target.as_os_str().to_string_lossy();
let mut path = if let Some(pid) = pid {
find_lib_in_proc_maps(pid, target_str).map_err(|io_error| UProbeError::FileError {
filename: format!("/proc/{pid}/maps"),
io_error,
})?
} else {
None
};
if path.is_none() {
path = if target.is_absolute() {
Some(target_str)
} else {
let cache =
LD_SO_CACHE
.as_ref()
.map_err(|error| UProbeError::InvalidLdSoCache {
io_error: error.clone(),
})?;
cache.resolve(target_str)
}
.map(String::from)
};
let path = path.ok_or(UProbeError::InvalidTarget {
path: target.to_owned(),
})?;
let sym_offset = if let Some(fn_name) = fn_name { let sym_offset = if let Some(fn_name) = fn_name {
resolve_symbol(&path, fn_name).map_err(|error| UProbeError::SymbolError { resolve_symbol(&path, fn_name).map_err(|error| UProbeError::SymbolError {
@ -152,6 +123,64 @@ impl UProbe {
} }
} }
fn resolve_attach_path<T: AsRef<Path>>(
target: T,
pid: Option<pid_t>,
) -> Result<String, UProbeError> {
// Look up the path for the target. If it there is a pid, and the target is a library name that
// is in the process's memory map, use the path of that library. Otherwise, use the target
// as-is.
let target = target.as_ref();
let target_str = &*target.as_os_str().to_string_lossy();
let mut path = if let Some(pid) = pid {
find_lib_in_proc_maps(pid, target_str).map_err(|io_error| UProbeError::FileError {
filename: format!("/proc/{pid}/maps"),
io_error,
})?
} else {
None
};
if path.is_none() {
path = if target.is_absolute() {
Some(target_str)
} else {
let cache = LD_SO_CACHE
.as_ref()
.map_err(|error| UProbeError::InvalidLdSoCache {
io_error: error.clone(),
})?;
cache.resolve(target_str)
}
.map(String::from)
};
path.ok_or(UProbeError::InvalidTarget {
path: target.to_owned(),
})
}
// Only run this test on linux with glibc because only in that configuration do we know that we'll
// be dynamically linked to libc and can exercise resolving the path to libc via the current
// process's memory map.
#[test]
#[cfg_attr(
any(miri, not(all(target_os = "linux", target_env = "gnu"))),
ignore = "requires glibc, doesn't work in miri"
)]
fn test_resolve_attach_path() {
// Look up the current process's pid.
let pid = std::process::id().try_into().unwrap();
// Now let's resolve the path to libc. It should exist in the current process's memory map and
// then in the ld.so.cache.
let libc_path = resolve_attach_path("libc", Some(pid)).unwrap();
// Make sure we got a path that contains libc.
assert!(libc_path.contains("libc"), "libc_path: {}", libc_path);
}
define_link_wrapper!( define_link_wrapper!(
/// The link used by [UProbe] programs. /// The link used by [UProbe] programs.
UProbeLink, UProbeLink,

@ -201,7 +201,9 @@ fn basic_uprobe() {
prog.load().unwrap(); prog.load().unwrap();
assert_loaded("test_uprobe"); assert_loaded("test_uprobe");
let link = prog.attach(Some("sleep"), 0, "libc", None).unwrap(); let link = prog
.attach(Some("uprobe_function"), 0, "/proc/self/exe", None)
.unwrap();
{ {
let _link_owned = prog.take_link(link).unwrap(); let _link_owned = prog.take_link(link).unwrap();
@ -213,7 +215,8 @@ fn basic_uprobe() {
prog.load().unwrap(); prog.load().unwrap();
assert_loaded("test_uprobe"); assert_loaded("test_uprobe");
prog.attach(Some("sleep"), 0, "libc", None).unwrap(); prog.attach(Some("uprobe_function"), 0, "/proc/self/exe", None)
.unwrap();
assert_loaded("test_uprobe"); assert_loaded("test_uprobe");
prog.unload().unwrap(); prog.unload().unwrap();
@ -424,14 +427,23 @@ fn pin_lifecycle_kprobe() {
assert_unloaded("test_kprobe"); assert_unloaded("test_kprobe");
} }
#[no_mangle]
#[inline(never)]
extern "C" fn uprobe_function() {
core::hint::black_box(uprobe_function);
}
#[test] #[test]
fn pin_lifecycle_uprobe() { fn pin_lifecycle_uprobe() {
const FIRST_PIN_PATH: &str = "/sys/fs/bpf/aya-uprobe-test-prog-1";
const SECOND_PIN_PATH: &str = "/sys/fs/bpf/aya-uprobe-test-prog-2";
// 1. Load Program and Pin // 1. Load Program and Pin
{ {
let mut bpf = Bpf::load(crate::TEST).unwrap(); let mut bpf = Bpf::load(crate::TEST).unwrap();
let prog: &mut UProbe = bpf.program_mut("test_uprobe").unwrap().try_into().unwrap(); let prog: &mut UProbe = bpf.program_mut("test_uprobe").unwrap().try_into().unwrap();
prog.load().unwrap(); prog.load().unwrap();
prog.pin("/sys/fs/bpf/aya-uprobe-test-prog").unwrap(); prog.pin(FIRST_PIN_PATH).unwrap();
} }
// should still be loaded since prog was pinned // should still be loaded since prog was pinned
@ -439,11 +451,7 @@ fn pin_lifecycle_uprobe() {
// 2. Load program from bpffs but don't attach it // 2. Load program from bpffs but don't attach it
{ {
let _ = UProbe::from_pin( let _ = UProbe::from_pin(FIRST_PIN_PATH, aya::programs::ProbeKind::UProbe).unwrap();
"/sys/fs/bpf/aya-uprobe-test-prog",
aya::programs::ProbeKind::UProbe,
)
.unwrap();
} }
// should still be loaded since prog was pinned // should still be loaded since prog was pinned
@ -451,17 +459,13 @@ fn pin_lifecycle_uprobe() {
// 3. Load program from bpffs and attach // 3. Load program from bpffs and attach
{ {
let mut prog = UProbe::from_pin( let mut prog = UProbe::from_pin(FIRST_PIN_PATH, aya::programs::ProbeKind::UProbe).unwrap();
"/sys/fs/bpf/aya-uprobe-test-prog", let link_id = prog
aya::programs::ProbeKind::UProbe, .attach(Some("uprobe_function"), 0, "/proc/self/exe", None)
) .unwrap();
.unwrap();
let link_id = prog.attach(Some("sleep"), 0, "libc", None).unwrap();
let link = prog.take_link(link_id).unwrap(); let link = prog.take_link(link_id).unwrap();
let fd_link: FdLink = link.try_into().unwrap(); let fd_link: FdLink = link.try_into().unwrap();
fd_link fd_link.pin(SECOND_PIN_PATH).unwrap();
.pin("/sys/fs/bpf/aya-uprobe-test-bash-sleep")
.unwrap();
// Unpin the program. It will stay attached since its links were pinned. // Unpin the program. It will stay attached since its links were pinned.
prog.unpin().unwrap(); prog.unpin().unwrap();
@ -472,7 +476,7 @@ fn pin_lifecycle_uprobe() {
// 4. unpin link, and make sure everything is unloaded // 4. unpin link, and make sure everything is unloaded
{ {
PinnedLink::from_pin("/sys/fs/bpf/aya-uprobe-test-bash-sleep") PinnedLink::from_pin(SECOND_PIN_PATH)
.unwrap() .unwrap()
.unpin() .unpin()
.unwrap(); .unwrap();
@ -480,4 +484,7 @@ fn pin_lifecycle_uprobe() {
// program should be unloaded // program should be unloaded
assert_unloaded("test_uprobe"); assert_unloaded("test_uprobe");
// Make sure the function isn't optimized out.
uprobe_function();
} }

Loading…
Cancel
Save