Merge pull request #796 from aya-rs/integration-ebpf-bpf-arch

integration-test: fix when host != target
pull/797/head
Tamir Duberstein 12 months ago committed by GitHub
commit 9eb0419baa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,19 +10,28 @@ use aya_bpf::{
const RESULT_BUF_LEN: usize = 1024; const RESULT_BUF_LEN: usize = 1024;
macro_rules! read_str_bytes { fn read_str_bytes(
($fun:ident, $ptr:expr, $len:expr $(,)?) => { fun: unsafe fn(*const u8, &mut [u8]) -> Result<&[u8], i64>,
iptr: Option<*const u8>,
ilen: Option<usize>,
) {
let Some(iptr) = iptr else {
return;
};
let Some(ilen) = ilen else {
return;
};
let Some(ptr) = RESULT.get_ptr_mut(0) else { let Some(ptr) = RESULT.get_ptr_mut(0) else {
return; return;
}; };
let TestResult { let dst = unsafe { ptr.as_mut() };
did_error, let Some(TestResult { buf, len }) = dst else {
len, return;
buf, };
} = unsafe { &mut *ptr }; *len = None;
// $len comes from ctx.arg(1) so it's dynamic and the verifier // len comes from ctx.arg(1) so it's dynamic and the verifier
// doesn't see any bounds. We do $len.min(RESULT_BUF_LEN) here to // doesn't see any bounds. We do len.min(RESULT_BUF_LEN) here to
// ensure that the verifier can see the upper bound, or you get: // ensure that the verifier can see the upper bound, or you get:
// //
// 18: (79) r7 = *(u64 *)(r7 +8) ; R7_w=scalar() // 18: (79) r7 = *(u64 *)(r7 +8) ; R7_w=scalar()
@ -31,26 +40,17 @@ macro_rules! read_str_bytes {
// R2_w=scalar(id=2,umax=9223372036854775807,var_off=(0x0; 0x7fffffffffffffff)) [snip] // R2_w=scalar(id=2,umax=9223372036854775807,var_off=(0x0; 0x7fffffffffffffff)) [snip]
// 28: (85) call bpf_probe_read_user_str#114 // 28: (85) call bpf_probe_read_user_str#114
// R2 unbounded memory access, use 'var &= const' or 'if (var < const)' // R2 unbounded memory access, use 'var &= const' or 'if (var < const)'
let Some(buf) = buf.get_mut(..$len) else { let Some(buf) = buf.get_mut(..ilen) else {
return; return;
}; };
match unsafe { $fun($ptr, buf) } { *len = Some(unsafe { fun(iptr, buf) }.map(<[_]>::len));
Ok(s) => {
*len = s.len();
}
Err(_) => {
*did_error = 1;
}
}
};
} }
#[repr(C)] #[repr(C)]
struct TestResult { struct TestResult {
did_error: u64,
len: usize,
buf: [u8; RESULT_BUF_LEN], buf: [u8; RESULT_BUF_LEN],
len: Option<Result<usize, i64>>,
} }
#[map] #[map]
@ -61,31 +61,22 @@ static KERNEL_BUFFER: Array<[u8; RESULT_BUF_LEN]> = Array::with_max_entries(1, 0
#[uprobe] #[uprobe]
pub fn test_bpf_probe_read_user_str_bytes(ctx: ProbeContext) { pub fn test_bpf_probe_read_user_str_bytes(ctx: ProbeContext) {
read_str_bytes!( read_str_bytes(
bpf_probe_read_user_str_bytes, bpf_probe_read_user_str_bytes,
match ctx.arg::<*const u8>(0) { ctx.arg::<*const u8>(0),
Some(p) => p, ctx.arg::<usize>(1),
_ => return,
},
match ctx.arg::<usize>(1) {
Some(p) => p,
_ => return,
},
); );
} }
#[uprobe] #[uprobe]
pub fn test_bpf_probe_read_kernel_str_bytes(ctx: ProbeContext) { pub fn test_bpf_probe_read_kernel_str_bytes(ctx: ProbeContext) {
read_str_bytes!( read_str_bytes(
bpf_probe_read_kernel_str_bytes, bpf_probe_read_kernel_str_bytes,
match KERNEL_BUFFER.get_ptr(0) { KERNEL_BUFFER
Some(p) => p as *const u8, .get_ptr(0)
_ => return, .and_then(|ptr| unsafe { ptr.as_ref() })
}, .map(|buf| buf.as_ptr()),
match ctx.arg::<usize>(0) { ctx.arg::<usize>(0),
Some(p) => p,
_ => return,
},
); );
} }

@ -107,7 +107,7 @@ fn main() {
} else if arch == "aarch64" { } else if arch == "aarch64" {
target_arch.push("arm64"); target_arch.push("arm64");
} else { } else {
target_arch.push(arch); target_arch.push(&arch);
}; };
// NB: libbpf's documentation suggests that vmlinux.h be generated by running `bpftool btf // NB: libbpf's documentation suggests that vmlinux.h be generated by running `bpftool btf
@ -198,6 +198,8 @@ fn main() {
&target, &target,
]); ]);
cmd.env("CARGO_CFG_BPF_TARGET_ARCH", arch);
// Workaround to make sure that the rust-toolchain.toml is respected. // Workaround to make sure that the rust-toolchain.toml is respected.
for key in ["RUSTUP_TOOLCHAIN", "RUSTC"] { for key in ["RUSTUP_TOOLCHAIN", "RUSTC"] {
cmd.env_remove(key); cmd.env_remove(key);

@ -5,9 +5,8 @@ const RESULT_BUF_LEN: usize = 1024;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
#[repr(C)] #[repr(C)]
struct TestResult { struct TestResult {
did_error: u64,
len: usize,
buf: [u8; RESULT_BUF_LEN], buf: [u8; RESULT_BUF_LEN],
len: Option<Result<usize, i64>>,
} }
unsafe impl aya::Pod for TestResult {} unsafe impl aya::Pod for TestResult {}
@ -96,11 +95,12 @@ fn set_kernel_buffer_element(bpf: &mut Bpf, bytes: &[u8]) {
#[track_caller] #[track_caller]
fn result_bytes(bpf: &Bpf) -> Vec<u8> { fn result_bytes(bpf: &Bpf) -> Vec<u8> {
let m = Array::<_, TestResult>::try_from(bpf.map("RESULT").unwrap()).unwrap(); let m = Array::<_, TestResult>::try_from(bpf.map("RESULT").unwrap()).unwrap();
let result = m.get(&0, 0).unwrap(); let TestResult { buf, len } = m.get(&0, 0).unwrap();
assert_eq!(result.did_error, 0); let len = len.unwrap();
let len = len.unwrap();
// assert that the buffer is always null terminated // assert that the buffer is always null terminated
assert_eq!(result.buf[result.len], 0); assert_eq!(buf[len], 0);
result.buf[..result.len].to_vec() buf[..len].to_vec()
} }
fn load_and_attach_uprobe(prog_name: &str, func_name: &str, bytes: &[u8]) -> Bpf { fn load_and_attach_uprobe(prog_name: &str, func_name: &str, bytes: &[u8]) -> Bpf {

Loading…
Cancel
Save