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. Kernel patchset: https://lore.kernel.org/bpf/20211210141652.877186-1-houtao1@huawei.com/pull/871/head
parent
38d8e32baa
commit
e80a462c3c
@ -0,0 +1,40 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
use core::cmp::Ordering;
|
||||||
|
|
||||||
|
use aya_bpf::{
|
||||||
|
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 str_bytes: *const u8 = ctx.arg(0).ok_or(-1)?;
|
||||||
|
let mut buf = [0u8; 16];
|
||||||
|
let str_bytes = unsafe { bpf_probe_read_user_str_bytes(str_bytes, &mut buf)? };
|
||||||
|
|
||||||
|
let ptr = RESULT.get_ptr_mut(0).ok_or(-1)?;
|
||||||
|
let dst = unsafe { ptr.as_mut() };
|
||||||
|
let TestResult(dst_res) = dst.ok_or(-1)?;
|
||||||
|
|
||||||
|
let cmp_res = bpf_strncmp(str_bytes, c"fff");
|
||||||
|
*dst_res = cmp_res;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
#[panic_handler]
|
||||||
|
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
use aya::{maps::Array, programs::UProbe, Bpf};
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct TestResult(Ordering);
|
||||||
|
|
||||||
|
unsafe impl aya::Pod for TestResult {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bpf_strncmp_equal() {
|
||||||
|
let bpf = load_and_attach_uprobe();
|
||||||
|
trigger_bpf_strncmp(b"fff".as_ptr());
|
||||||
|
let res = fetch_result(&bpf);
|
||||||
|
assert_eq!(res, Ordering::Equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bpf_strncmp_equal_longer() {
|
||||||
|
let bpf = load_and_attach_uprobe();
|
||||||
|
trigger_bpf_strncmp(b"ffffff".as_ptr());
|
||||||
|
let res = fetch_result(&bpf);
|
||||||
|
assert_eq!(res, Ordering::Equal);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bpf_strncmp_less() {
|
||||||
|
let bpf = load_and_attach_uprobe();
|
||||||
|
trigger_bpf_strncmp(b"aaa".as_ptr());
|
||||||
|
let res = fetch_result(&bpf);
|
||||||
|
assert_eq!(res, Ordering::Less);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bpf_strncmp_greater() {
|
||||||
|
let bpf = load_and_attach_uprobe();
|
||||||
|
trigger_bpf_strncmp(b"zzz".as_ptr());
|
||||||
|
let res = fetch_result(&bpf);
|
||||||
|
assert_eq!(res, Ordering::Greater);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_and_attach_uprobe() -> Bpf {
|
||||||
|
let mut bpf = Bpf::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();
|
||||||
|
|
||||||
|
bpf
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_result(bpf: &Bpf) -> Ordering {
|
||||||
|
let array = Array::<_, TestResult>::try_from(bpf.map("RESULT").unwrap()).unwrap();
|
||||||
|
let TestResult(res) = array.get(&0, 0).unwrap();
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
#[inline(never)]
|
||||||
|
pub extern "C" fn trigger_bpf_strncmp(string: *const u8) {
|
||||||
|
core::hint::black_box(string);
|
||||||
|
}
|
Loading…
Reference in New Issue