From ee3372f7aa9aa369be7bdc5e3c638f8c8bef31f4 Mon Sep 17 00:00:00 2001 From: Tamir Duberstein Date: Fri, 3 Oct 2025 11:23:24 -0400 Subject: [PATCH] integration-test: add LSM --- test-distro/src/init.rs | 8 ++++++ test/integration-ebpf/src/test.rs | 21 ++++++++-------- test/integration-test/src/tests.rs | 1 + test/integration-test/src/tests/lsm.rs | 35 ++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 11 deletions(-) create mode 100644 test/integration-test/src/tests/lsm.rs diff --git a/test-distro/src/init.rs b/test-distro/src/init.rs index e9030bc7..3c76e946 100644 --- a/test-distro/src/init.rs +++ b/test-distro/src/init.rs @@ -89,6 +89,14 @@ fn run() -> anyhow::Result<()> { data: None, target_mode: None, }, + Mount { + source: "securityfs", + target: "/sys/kernel/security", + fstype: "securityfs", + flags: nix::mount::MsFlags::empty(), + data: None, + target_mode: None, + }, ] { match target_mode { None => { diff --git a/test/integration-ebpf/src/test.rs b/test/integration-ebpf/src/test.rs index b9c4bfdf..9d0dbde4 100644 --- a/test/integration-ebpf/src/test.rs +++ b/test/integration-ebpf/src/test.rs @@ -4,24 +4,18 @@ use aya_ebpf::{ bindings::{bpf_ret_code, xdp_action}, - macros::{flow_dissector, kprobe, kretprobe, tracepoint, uprobe, uretprobe, xdp}, + macros::{flow_dissector, kprobe, kretprobe, lsm, tracepoint, uprobe, uretprobe, xdp}, programs::{ - FlowDissectorContext, ProbeContext, RetProbeContext, TracePointContext, XdpContext, + FlowDissectorContext, LsmContext, ProbeContext, RetProbeContext, TracePointContext, + XdpContext, }, }; #[cfg(not(test))] extern crate ebpf_panic; #[xdp] -fn pass(ctx: XdpContext) -> u32 { - match unsafe { try_pass(ctx) } { - Ok(ret) => ret, - Err(_) => xdp_action::XDP_ABORTED, - } -} - -unsafe fn try_pass(_ctx: XdpContext) -> Result { - Ok(xdp_action::XDP_PASS) +fn pass(_ctx: XdpContext) -> u32 { + xdp_action::XDP_PASS } #[kprobe] @@ -55,3 +49,8 @@ fn test_flow(_ctx: FlowDissectorContext) -> u32 { // Linux kernel for inspiration. bpf_ret_code::BPF_FLOW_DISSECTOR_CONTINUE } + +#[lsm(hook = "file_open")] +fn test_file_open(_ctx: LsmContext) -> i32 { + 1 // Disallow. +} diff --git a/test/integration-test/src/tests.rs b/test/integration-test/src/tests.rs index 0e376c5a..82ec927b 100644 --- a/test/integration-test/src/tests.rs +++ b/test/integration-test/src/tests.rs @@ -8,6 +8,7 @@ mod iter; mod linear_data_structures; mod load; mod log; +mod lsm; mod map_pin; mod raw_tracepoint; mod rbpf; diff --git a/test/integration-test/src/tests/lsm.rs b/test/integration-test/src/tests/lsm.rs new file mode 100644 index 00000000..ce7e4e87 --- /dev/null +++ b/test/integration-test/src/tests/lsm.rs @@ -0,0 +1,35 @@ +use aya::{Btf, Ebpf, programs::Lsm, sys::is_program_supported}; + +#[test] +fn lsm() { + if !is_program_supported(aya::programs::ProgramType::Lsm).unwrap() { + eprintln!("LSM programs are not supported"); + return; + } + if !std::fs::read_to_string("/sys/kernel/security/lsm") + .unwrap() + .contains("bpf") + { + eprintln!("bpf is not enabled in LSM"); + return; + } + + let btf = Btf::from_sys_fs().unwrap(); + if let Err(e) = btf.id_by_type_name_kind("bpf_lsm_bpf", aya_obj::btf::BtfKind::Func) { + eprintln!("bpf_lsm_bpf is not found in BTF: {e}"); + return; + } + + let mut bpf: Ebpf = Ebpf::load(crate::TEST).unwrap(); + let prog = bpf.program_mut("test_file_open").unwrap(); + let prog: &mut Lsm = prog.try_into().unwrap(); + prog.load("file_open", &btf).unwrap(); + + assert_matches::assert_matches!(std::fs::File::open("/proc/self/exe"), Ok(_)); + + prog.attach().unwrap(); + + assert_matches::assert_matches!(std::fs::File::open("/proc/self/exe"), Err(e) => assert_eq!( + e.kind(), std::io::ErrorKind::PermissionDenied) + ); +}