Skip to content

Commit

Permalink
integration-test: attach uprobes to self
Browse files Browse the repository at this point in the history
For unclear reasons, two of the integration tests related to uprobes
were resolving a symbol in libc. The integration-test binary can be
built statically, in which case it would not load or reference libc.
Statically linking the integration tests and running them in a VM
without a userland is a convenient mechanism to exercise the tests
against different kernel versions.

The fact that the statically linked integration-test binary does not
load libc is not the only reason these tests failed in such an
environment. In fact, the logic to look in the process's memory
maps was not running (because no pid was being passed).

Separate logic to determine which object file to use when attempting
to resolve a symbol for attaching a uprobe changes its behavior based
on whether that target is an absolute path. If the target is not an
absolute path, the code searches through the LdSoCache. This cache does
not always exist in linux systems; when an attach call is made with a
relative path target and there is no /etc/ld.so.cache file, the attach
call will fail. This commit does not change that behavior, it merely
sidesteps it.
  • Loading branch information
ajwerner committed Aug 2, 2023
1 parent a64cbd8 commit de1deb8
Showing 1 changed file with 26 additions and 18 deletions.
44 changes: 26 additions & 18 deletions test/integration-test/src/tests/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,9 @@ fn basic_uprobe() {

prog.load().unwrap();
assert_loaded!("test_uprobe", true);
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();
Expand All @@ -207,7 +209,8 @@ fn basic_uprobe() {
prog.load().unwrap();

assert_loaded!("test_uprobe", true);
prog.attach(Some("sleep"), 0, "libc", None).unwrap();
prog.attach(Some("uprobe_function"), 0, "/proc/self/exe", None)
.unwrap();

assert_loaded!("test_uprobe", true);
prog.unload().unwrap();
Expand Down Expand Up @@ -418,44 +421,46 @@ fn pin_lifecycle_kprobe() {
assert_loaded!("test_kprobe", false);
}

#[no_mangle]
#[inline(never)]
extern "C" fn uprobe_function() {
core::hint::black_box(uprobe_function);
}

#[test]
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
{
let mut bpf = Bpf::load(crate::TEST).unwrap();
let prog: &mut UProbe = bpf.program_mut("test_uprobe").unwrap().try_into().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
assert_loaded!("test_uprobe", true);

// 2. Load program from bpffs but don't attach it
{
let _ = UProbe::from_pin(
"/sys/fs/bpf/aya-uprobe-test-prog",
aya::programs::ProbeKind::UProbe,
)
.unwrap();
let _ = UProbe::from_pin(FIRST_PIN_PATH, aya::programs::ProbeKind::UProbe).unwrap();
}

// should still be loaded since prog was pinned
assert_loaded!("test_uprobe", true);

// 3. Load program from bpffs and attach
{
let mut prog = UProbe::from_pin(
"/sys/fs/bpf/aya-uprobe-test-prog",
aya::programs::ProbeKind::UProbe,
)
.unwrap();
let link_id = prog.attach(Some("sleep"), 0, "libc", None).unwrap();
let mut prog =
UProbe::from_pin(FIRST_PIN_PATH, aya::programs::ProbeKind::UProbe).unwrap();
let link_id = prog
.attach(Some("uprobe_function"), 0, "/proc/self/exe", None)
.unwrap();
let link = prog.take_link(link_id).unwrap();
let fd_link: FdLink = link.try_into().unwrap();
fd_link
.pin("/sys/fs/bpf/aya-uprobe-test-bash-sleep")
.unwrap();
fd_link.pin(SECOND_PIN_PATH).unwrap();

// Unpin the program. It will stay attached since its links were pinned.
prog.unpin().unwrap();
Expand All @@ -466,12 +471,15 @@ fn pin_lifecycle_uprobe() {

// 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()
.unpin()
.unwrap();
}

// program should be unloaded
assert_loaded!("test_uprobe", false);

// Make sure the function isn't optimized out.
uprobe_function();
}

0 comments on commit de1deb8

Please sign in to comment.