Skip to content

Commit

Permalink
fixup and add tests (known broken)
Browse files Browse the repository at this point in the history
  • Loading branch information
addisoncrump committed Apr 5, 2024
1 parent 4174b03 commit ffcd324
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 133 deletions.
8 changes: 8 additions & 0 deletions ebpf/aya-ebpf/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ unsafe impl<T> FromBtfArgument for *const T {
}
}

unsafe impl<T> FromBtfArgument for *mut T {
unsafe fn from_argument(ctx: *const c_void, n: usize) -> *mut T {
// BTF arguments are exposed as an array of `usize` where `usize` can
// either be treated as a pointer or a primitive type
*(ctx as *const usize).add(n) as _
}
}

/// Helper macro to implement [`FromBtfArgument`] for a primitive type.
macro_rules! unsafe_impl_from_btf_argument {
($type:ident) => {
Expand Down
2 changes: 1 addition & 1 deletion ebpf/aya-ebpf/src/maps/inode_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ const fn build_def<V>(ty: u32, flags: u32, pin: PinningType) -> bpf_map_def {
type_: ty,
key_size: mem::size_of::<c_int>() as u32,
value_size: mem::size_of::<V>() as u32,
max_entries: 0,
max_entries: 1,
map_flags: flags,
id: 0,
pinning: pin as u32,
Expand Down
2 changes: 1 addition & 1 deletion ebpf/aya-ebpf/src/programs/lsm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl LsmContext {
///
/// [1]: https://elixir.bootlin.com/linux/latest/source/include/linux/lsm_hook_defs.h
pub unsafe fn arg<T: FromBtfArgument>(&self, n: usize) -> T {
T::from_argument(self.ctx as *const _, n)
T::from_argument(self.ctx, n)
}
}

Expand Down
40 changes: 38 additions & 2 deletions test/integration-ebpf/src/inode_storage.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,46 @@
//! The purpose of this test is to identify if we can prevent a tmpfile from being linked to by
//! storing information in inode storage.

#![no_std]
#![no_main]

use aya_ebpf::{macros::map, maps::inode_storage::InodeStorage};
use aya_ebpf::{
bindings::BPF_F_NO_PREALLOC,
cty::c_void,
macros::{lsm, map},
maps::inode_storage::InodeStorage,
programs::LsmContext,
};
use aya_log_ebpf::warn;

#[map]
static INODE_STORE: InodeStorage<usize> = InodeStorage::new(0);
static TMP_INODE_STORE: InodeStorage<usize> = InodeStorage::new(BPF_F_NO_PREALLOC);

#[lsm(hook = "inode_post_create_tmpfile")]
pub fn inode_post_create_tmpfile(ctx: LsmContext) -> i32 {
unsafe { try_inode_post_create_tmpfile(ctx) }.unwrap_or_else(|ret| ret)
}

unsafe fn try_inode_post_create_tmpfile(ctx: LsmContext) -> Result<i32, i32> {
let tmpfile: *mut c_void = ctx.arg(1);
if TMP_INODE_STORE.get_or_insert_ptr(tmpfile, &0).is_none() {
warn!(&ctx, "Couldn't add information that we deleted a tmp node!");
}
Ok(0)
}

#[lsm(hook = "inode_link")]
pub fn inode_link(ctx: LsmContext) -> i32 {
unsafe { try_inode_link(ctx) }.unwrap_or_else(|ret| ret)
}

unsafe fn try_inode_link(ctx: LsmContext) -> Result<i32, i32> {
let maybe_tmpfile: *mut c_void = ctx.arg(0);
if TMP_INODE_STORE.get(maybe_tmpfile).is_some() {
return Err(130);
}
Ok(0)
}

#[cfg(not(test))]
#[panic_handler]
Expand Down
2 changes: 2 additions & 0 deletions test/integration-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub const TEXT_64_64_RELOC: &[u8] =

pub const LOG: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/log"));
pub const MAP_TEST: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/map_test"));
pub const INODE_STORAGE_TEST: &[u8] =
include_bytes_aligned!(concat!(env!("OUT_DIR"), "/inode_storage"));
pub const NAME_TEST: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/name_test"));
pub const PASS: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/pass"));
pub const TEST: &[u8] = include_bytes_aligned!(concat!(env!("OUT_DIR"), "/test"));
Expand Down
1 change: 1 addition & 0 deletions test/integration-test/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod bpf_probe_read;
mod btf_relocations;
mod elf;
mod inode_storage;
mod load;
mod log;
mod rbpf;
Expand Down
49 changes: 49 additions & 0 deletions test/integration-test/src/tests/inode_storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use std::{
error::Error,
fs::OpenOptions,
os::{fd::IntoRawFd, unix::fs::OpenOptionsExt},
};

use aya::{programs::Lsm, Ebpf};
use aya_obj::btf::Btf;
use libc::{linkat, AT_EMPTY_PATH, AT_FDCWD, O_TMPFILE};

use crate::INODE_STORAGE_TEST;

#[test]
fn no_link_to_tmp() -> Result<(), Box<dyn Error>> {
let mut bpf = Ebpf::load(INODE_STORAGE_TEST)?;
let btf = Btf::from_sys_fs()?;

let rename: &mut Lsm = bpf
.program_mut("inode_post_create_tmpfile")
.unwrap()
.try_into()?;
rename.load("inode_post_create_tmpfile", &btf)?;
rename.attach()?;

let link: &mut Lsm = bpf.program_mut("inode_link").unwrap().try_into()?;
link.load("inode_link", &btf)?;
link.attach()?;

// create a temporary file
let tmpfile = OpenOptions::new()
.custom_flags(O_TMPFILE)
.create_new(true)
.open("/tmp/")?;

let fd = tmpfile.into_raw_fd();
let res = unsafe {
linkat(
fd,
c"".as_ptr(),
AT_FDCWD,
c"/tmp/blah".as_ptr(),
AT_EMPTY_PATH,
)
};

assert_eq!(130, res);

Ok(())
}

0 comments on commit ffcd324

Please sign in to comment.