浏览代码

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

integration-test: fix when host != target
Tamir Duberstein 1 年之前
父节点
当前提交
9eb0419baa

+ 43 - 52
test/integration-ebpf/src/bpf_probe_read.rs

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

+ 3 - 1
test/integration-test/build.rs

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

+ 6 - 6
test/integration-test/src/tests/bpf_probe_read.rs

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