From 479b342347c89ff0eb4836ab7bce35216e1f60ca Mon Sep 17 00:00:00 2001 From: Xiaobo Liu Date: Sat, 23 Aug 2025 17:42:14 +0800 Subject: [PATCH 1/3] ebpf: add bpf_d_path helper function Signed-off-by: Xiaobo Liu --- ebpf/aya-ebpf/src/helpers.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ebpf/aya-ebpf/src/helpers.rs b/ebpf/aya-ebpf/src/helpers.rs index be009e90..c0fea236 100644 --- a/ebpf/aya-ebpf/src/helpers.rs +++ b/ebpf/aya-ebpf/src/helpers.rs @@ -15,7 +15,7 @@ use core::{ mem::{self, MaybeUninit}, }; -pub use aya_ebpf_bindings::helpers as generated; +pub use aya_ebpf_bindings::{bindings::path, helpers as generated}; #[doc(hidden)] pub use generated::*; @@ -842,3 +842,14 @@ pub fn bpf_strncmp(s1: &[u8; N], s2: &CStr) -> Ordering { unsafe { generated::bpf_strncmp(s1.as_ptr() as *const _, N as u32, s2.as_ptr() as *const _) } .cmp(&0) } + +#[inline] +pub unsafe fn bpf_d_path(path: *const path, dest: &mut [u8]) -> Result<&[u8], c_long> { + let len = generated::bpf_d_path( + path as *mut path, + dest.as_mut_ptr() as *mut _, + dest.len() as u32, + ); + + read_str_bytes(len, dest) +} From 570c505e774f1147df8aa607cf1e7c157ea86baf Mon Sep 17 00:00:00 2001 From: Xiaobo Liu Date: Sun, 24 Aug 2025 10:20:18 +0800 Subject: [PATCH 2/3] update public-api Signed-off-by: Xiaobo Liu --- xtask/public-api/aya-ebpf.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xtask/public-api/aya-ebpf.txt b/xtask/public-api/aya-ebpf.txt index 2d70495b..16621936 100644 --- a/xtask/public-api/aya-ebpf.txt +++ b/xtask/public-api/aya-ebpf.txt @@ -4,6 +4,7 @@ pub use aya_ebpf::cty pub use aya_ebpf::macros pub mod aya_ebpf::helpers pub use aya_ebpf::helpers::generated +pub use aya_ebpf::helpers::path pub macro aya_ebpf::helpers::bpf_printk! #[repr(transparent)] pub struct aya_ebpf::helpers::PrintkArg(_) impl aya_ebpf::helpers::PrintkArg @@ -61,6 +62,7 @@ impl core::clone::CloneToUninit for aya_ebpf::helpers::PrintkArg where T: cor pub unsafe fn aya_ebpf::helpers::PrintkArg::clone_to_uninit(&self, dest: *mut u8) impl core::convert::From for aya_ebpf::helpers::PrintkArg pub fn aya_ebpf::helpers::PrintkArg::from(t: T) -> T +pub unsafe fn aya_ebpf::helpers::bpf_d_path(path: *const aya_ebpf_bindings::x86_64::bindings::path, dest: &mut [u8]) -> core::result::Result<&[u8], aya_ebpf_cty::od::c_long> pub fn aya_ebpf::helpers::bpf_get_current_comm() -> core::result::Result<[u8; 16], aya_ebpf_cty::od::c_long> pub fn aya_ebpf::helpers::bpf_get_current_pid_tgid() -> u64 pub fn aya_ebpf::helpers::bpf_get_current_uid_gid() -> u64 From 10f39c7354d5cf44d3db70ad638dccb2d1cd1ec9 Mon Sep 17 00:00:00 2001 From: Xiaobo Liu Date: Sun, 7 Sep 2025 21:35:44 +0800 Subject: [PATCH 3/3] add test Signed-off-by: Xiaobo Liu --- test/integration-common/src/lib.rs | 14 +++++ test/integration-ebpf/Cargo.toml | 4 ++ test/integration-ebpf/src/bpf_d_path.rs | 51 +++++++++++++++++++ test/integration-test/src/lib.rs | 1 + test/integration-test/src/tests.rs | 1 + test/integration-test/src/tests/bpf_d_path.rs | 42 +++++++++++++++ 6 files changed, 113 insertions(+) create mode 100644 test/integration-ebpf/src/bpf_d_path.rs create mode 100644 test/integration-test/src/tests/bpf_d_path.rs 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() +}