Merge pull request #142 from vadorovsky/args-mut-ptr

aya-bpf: Add bpf_probe_write_user helper
pull/152/head
Alessandro Decina 3 years ago committed by GitHub
commit 923cd9b767
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -168,7 +168,7 @@ pub fn raw_tracepoint(attrs: TokenStream, item: TokenStream) -> TokenStream {
/// Marks a function as an LSM program that can be attached to Linux LSM hooks.
/// Used to implement security policy and audit logging.
///
/// LSM probes can be attached to the kernel's [security hooks][1] to implement mandatory
/// LSM probes can be attached to the kernel's security hooks to implement mandatory
/// access control policy and security auditing.
///
/// LSM probes require a kernel compiled with `CONFIG_BPF_LSM=y` and `CONFIG_DEBUG_INFO_BTF=y`.

@ -120,6 +120,55 @@ impl<T> FromPtRegs for *const T {
}
}
#[cfg(bpf_target_arch = "x86_64")]
impl<T> FromPtRegs for *mut T {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
match n {
0 => ctx.rdi().map(|v| v as _),
1 => ctx.rsi().map(|v| v as _),
2 => ctx.rdx().map(|v| v as _),
3 => ctx.rcx().map(|v| v as _),
4 => ctx.r8().map(|v| v as _),
5 => ctx.r9().map(|v| v as _),
_ => None,
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
ctx.rax().map(|v| v as _)
}
}
#[cfg(bpf_target_arch = "armv7")]
impl<T> FromPtRegs for *mut T {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
if n <= 6 {
ctx.uregs().map(|regs| regs[n] as _)
} else {
None
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
ctx.uregs().map(|regs| regs[0] as _)
}
}
#[cfg(bpf_target_arch = "aarch64")]
impl<T> FromPtRegs for *mut T {
fn from_argument(ctx: &pt_regs, n: usize) -> Option<Self> {
if n <= 7 {
ctx.regs().map(|regs| regs[n] as _)
} else {
None
}
}
fn from_retval(ctx: &pt_regs) -> Option<Self> {
ctx.regs().map(|regs| regs[0] as _)
}
}
/// Helper macro to implement [`FromPtRegs`] for a primitive type.
macro_rules! impl_from_pt_regs {
($type:ident) => {

@ -364,6 +364,45 @@ pub unsafe fn bpf_probe_read_kernel_str(src: *const u8, dest: &mut [u8]) -> Resu
Ok(len as usize)
}
/// Write bytes to the _user space_ pointer `src` and store them as a `T`.
///
/// # Examples
///
/// ```no_run
/// # #![allow(dead_code)]
/// # use aya_bpf::{
/// # cty::{c_int, c_long},
/// # helpers::bpf_probe_write_user,
/// # programs::ProbeContext,
/// # };
/// fn try_test(ctx: ProbeContext) -> Result<(), c_long> {
/// let retp: *mut c_int = ctx.arg(0).ok_or(1)?;
/// let val: i32 = 1;
/// // Write the value to the userspace pointer.
/// unsafe { bpf_probe_write_user(retp, &val as *const i32)? };
///
/// Ok::<(), c_long>(())
/// }
/// ```
///
/// # Errors
///
/// On failure, this function returns a negative value wrapped in an `Err`.
#[allow(clippy::fn_to_numeric_cast_with_truncation)]
#[inline]
pub unsafe fn bpf_probe_write_user<T>(dst: *mut T, src: *const T) -> Result<(), c_long> {
let ret = gen::bpf_probe_write_user(
dst as *mut c_void,
src as *const c_void,
mem::size_of::<T>() as u32,
);
if ret < 0 {
return Err(ret);
}
Ok(())
}
/// Read the `comm` field associated with the current task struct
/// as a `[c_char; 16]`.
///

Loading…
Cancel
Save