diff --git a/test/integration-common/src/lib.rs b/test/integration-common/src/lib.rs index f75a3939..b17a8d31 100644 --- a/test/integration-common/src/lib.rs +++ b/test/integration-common/src/lib.rs @@ -64,3 +64,17 @@ pub mod strncmp { #[cfg(feature = "user")] unsafe impl aya::Pod for TestResult {} } + +pub mod bpf_d_path { + pub const PATH_BUF_LEN: usize = 128; + + #[derive(Copy, Clone)] + #[repr(C)] + pub struct TestResult { + pub buf: [u8; PATH_BUF_LEN], + pub len: usize, + } + + #[cfg(feature = "user")] + unsafe impl aya::Pod for TestResult {} +} diff --git a/test/integration-ebpf/Cargo.toml b/test/integration-ebpf/Cargo.toml index b0573882..d4e860e0 100644 --- a/test/integration-ebpf/Cargo.toml +++ b/test/integration-ebpf/Cargo.toml @@ -28,6 +28,10 @@ xtask = { path = "../../xtask" } name = "bpf_probe_read" path = "src/bpf_probe_read.rs" +[[bin]] +name = "bpf_d_path" +path = "src/bpf_d_path.rs" + [[bin]] name = "log" path = "src/log.rs" diff --git a/test/integration-ebpf/src/bpf_d_path.rs b/test/integration-ebpf/src/bpf_d_path.rs new file mode 100644 index 00000000..9a04bf9a --- /dev/null +++ b/test/integration-ebpf/src/bpf_d_path.rs @@ -0,0 +1,51 @@ +#![no_std] +#![no_main] + +use aya_ebpf::{ + bindings::path, + cty::c_long, + helpers::bpf_d_path, + macros::{fentry, map}, + maps::Array, + memcpy, + programs::FEntryContext, +}; +use integration_common::bpf_d_path::{PATH_BUF_LEN, TestResult}; +#[cfg(not(test))] +extern crate ebpf_panic; + +#[map] +static RESULT: Array = Array::with_max_entries(1, 0); + +#[fentry] +pub fn test_vfs_open(ctx: FEntryContext) -> u32 { + match try_vfs_open(ctx) { + Ok(_) => 0, + Err(_) => 1, + } +} + +fn try_vfs_open(ctx: FEntryContext) -> Result<(), c_long> { + let dest = &mut [0u8; PATH_BUF_LEN]; + let pathptr: *const path = unsafe { ctx.arg(0) }; + let data = unsafe { bpf_d_path(pathptr, dest)? }; + + let mut result = TestResult { + buf: [0u8; PATH_BUF_LEN], + len: 0, + }; + + unsafe { + memcpy( + result.buf.as_mut_ptr(), + data.as_ptr() as *mut u8, + data.len(), + ) + }; + + result.len = dest.len(); + + RESULT.set(0, &result, 0)?; + + Ok(()) +} diff --git a/test/integration-test/src/lib.rs b/test/integration-test/src/lib.rs index f7cc30c6..533fd3d9 100644 --- a/test/integration-test/src/lib.rs +++ b/test/integration-test/src/lib.rs @@ -38,6 +38,7 @@ bpf_file!( TEXT_64_64_RELOC => "text_64_64_reloc.o", VARIABLES_RELOC => "variables_reloc.bpf.o", + BPF_D_PATH => "bpf_d_path", BPF_PROBE_READ => "bpf_probe_read", LOG => "log", MAP_TEST => "map_test", diff --git a/test/integration-test/src/tests.rs b/test/integration-test/src/tests.rs index 43894366..ef0f51c3 100644 --- a/test/integration-test/src/tests.rs +++ b/test/integration-test/src/tests.rs @@ -1,3 +1,4 @@ +mod bpf_d_path; mod bpf_probe_read; mod btf_relocations; mod elf; diff --git a/test/integration-test/src/tests/bpf_d_path.rs b/test/integration-test/src/tests/bpf_d_path.rs new file mode 100644 index 00000000..3ac9f348 --- /dev/null +++ b/test/integration-test/src/tests/bpf_d_path.rs @@ -0,0 +1,42 @@ +use std::fs::File; + +use aya::{Btf, Ebpf, maps::Array, programs::FEntry}; +use integration_common::bpf_d_path::TestResult; + +#[test_log::test] +fn bpf_d_path_basic() { + let btf = Btf::from_sys_fs().unwrap(); + let mut bpf = Ebpf::load(crate::BPF_D_PATH).unwrap(); + let prog: &mut FEntry = bpf + .program_mut("test_vfs_open") + .unwrap() + .try_into() + .unwrap(); + prog.load("vfs_open", &btf).unwrap(); + prog.attach().unwrap(); + + let file = File::open("/dev/null").unwrap(); + + let result = get_result(&bpf); + + let path_len = result.len; + assert!(path_len > 0, "Path length should be greater than 0"); + assert!( + path_len <= result.buf.len(), + "Path length should not exceed buffer size" + ); + + let path_str = std::str::from_utf8(&result.buf[..path_len]).unwrap(); + assert!( + path_str.contains("/dev/null"), + "Path should contain '/dev/null', got: {}", + path_str + ); + + drop(file); +} + +fn get_result(bpf: &Ebpf) -> TestResult { + let m = Array::<_, TestResult>::try_from(bpf.map("RESULT").unwrap()).unwrap(); + m.get(&0, 0).unwrap() +}