mirror of https://github.com/aya-rs/aya
bpf: Add `bpf_strncmp` helper
The `bpf_strncmp` helper allows for better string comparison in eBPF programs. Added in https://github.com/torvalds/linux/commit/c5fb19937455095573a19.reviewable/pr543/r1
parent
2e4650e5a5
commit
0b58d3eb6d
@ -0,0 +1,38 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::cmp::Ordering;
|
||||
|
||||
use aya_ebpf::{
|
||||
cty::c_long,
|
||||
helpers::{bpf_probe_read_user_str_bytes, bpf_strncmp},
|
||||
macros::{map, uprobe},
|
||||
maps::Array,
|
||||
programs::ProbeContext,
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
struct TestResult(Ordering);
|
||||
|
||||
#[map]
|
||||
static RESULT: Array<TestResult> = Array::with_max_entries(1, 0);
|
||||
|
||||
#[uprobe]
|
||||
pub fn test_bpf_strncmp(ctx: ProbeContext) -> Result<(), c_long> {
|
||||
let s1: *const u8 = ctx.arg(0).ok_or(-1)?;
|
||||
let mut b1 = [0u8; 3];
|
||||
let _: &[u8] = unsafe { bpf_probe_read_user_str_bytes(s1, &mut b1) }?;
|
||||
|
||||
let ptr = RESULT.get_ptr_mut(0).ok_or(-1)?;
|
||||
let dst = unsafe { ptr.as_mut() };
|
||||
let TestResult(dst_res) = dst.ok_or(-1)?;
|
||||
*dst_res = bpf_strncmp(&b1, c"ff");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
ffi::{c_char, CStr},
|
||||
};
|
||||
|
||||
use aya::{
|
||||
maps::{Array, MapData},
|
||||
programs::UProbe,
|
||||
Ebpf,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
struct TestResult(Ordering);
|
||||
|
||||
unsafe impl aya::Pod for TestResult {}
|
||||
|
||||
#[test]
|
||||
fn bpf_strncmp() {
|
||||
let mut bpf = Ebpf::load(crate::STRNCMP).unwrap();
|
||||
|
||||
{
|
||||
let prog: &mut UProbe = bpf
|
||||
.program_mut("test_bpf_strncmp")
|
||||
.unwrap()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
prog.load().unwrap();
|
||||
|
||||
prog.attach(Some("trigger_bpf_strncmp"), 0, "/proc/self/exe", None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let array = Array::<_, TestResult>::try_from(bpf.map("RESULT").unwrap()).unwrap();
|
||||
|
||||
assert_eq!(do_bpf_strncmp(&array, c"ff"), Ordering::Equal);
|
||||
|
||||
// This is truncated in BPF; the buffer size is 3 including the null terminator.
|
||||
assert_eq!(do_bpf_strncmp(&array, c"fff"), Ordering::Equal);
|
||||
|
||||
assert_eq!(do_bpf_strncmp(&array, c"aa"), Ordering::Less);
|
||||
assert_eq!(do_bpf_strncmp(&array, c"zz"), Ordering::Greater);
|
||||
}
|
||||
|
||||
fn do_bpf_strncmp(array: &Array<&MapData, TestResult>, s1: &CStr) -> Ordering {
|
||||
trigger_bpf_strncmp(s1.as_ptr());
|
||||
let TestResult(ord) = array.get(&0, 0).unwrap();
|
||||
ord
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
#[inline(never)]
|
||||
pub extern "C" fn trigger_bpf_strncmp(s1: *const c_char) {
|
||||
core::hint::black_box(s1);
|
||||
}
|
Loading…
Reference in New Issue