diff --git a/aya-ebpf-macros/src/lib.rs b/aya-ebpf-macros/src/lib.rs index d5811d53..5dac48db 100644 --- a/aya-ebpf-macros/src/lib.rs +++ b/aya-ebpf-macros/src/lib.rs @@ -11,6 +11,7 @@ mod fexit; mod flow_dissector; mod kprobe; mod lsm; +mod lsm_cgroup; mod map; mod perf_event; mod raw_tracepoint; @@ -36,6 +37,7 @@ use fexit::FExit; use flow_dissector::FlowDissector; use kprobe::{KProbe, KProbeKind}; use lsm::Lsm; +use lsm_cgroup::LsmCgroup; use map::Map; use perf_event::PerfEvent; use proc_macro::TokenStream; @@ -328,6 +330,49 @@ pub fn lsm(attrs: TokenStream, item: TokenStream) -> TokenStream { .into() } +/// Marks a function as an LSM program that can be attached to cgroups. +/// This program will only trigger for workloads in the attached cgroups. +/// Used to implement security policy and audit logging. +/// +/// The hook name is the first and only argument to the macro. +/// +/// 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`. +/// In order for the probes to fire, you also need the BPF LSM to be enabled through your +/// kernel's boot paramters (like `lsm=lockdown,yama,bpf`). +/// +/// # Minimum kernel version +/// +/// The minimum kernel version required to use this feature is 6.0. +/// +/// # Examples +/// +/// ```no_run +/// use aya_ebpf::{macros::lsm_cgroup, programs::LsmContext}; +/// +/// #[lsm_cgroup(hook = "file_open")] +/// pub fn file_open(ctx: LsmContext) -> i32 { +/// match unsafe { try_file_open(ctx) } { +/// Ok(ret) => ret, +/// Err(ret) => ret, +/// } +/// } +/// +/// unsafe fn try_file_open(_ctx: LsmContext) -> Result { +/// Err(0) +/// } +/// ``` +#[proc_macro_attribute] +pub fn lsm_cgroup(attrs: TokenStream, item: TokenStream) -> TokenStream { + match LsmCgroup::parse(attrs.into(), item.into()) { + Ok(prog) => prog.expand(), + Err(err) => err.into_compile_error(), + } + .into() +} + /// Marks a function as a [BTF-enabled raw tracepoint][1] eBPF program that can be attached at /// a pre-defined kernel trace point. /// diff --git a/aya-ebpf-macros/src/lsm.rs b/aya-ebpf-macros/src/lsm.rs index e5c530c4..bdc688b6 100644 --- a/aya-ebpf-macros/src/lsm.rs +++ b/aya-ebpf-macros/src/lsm.rs @@ -44,10 +44,10 @@ impl Lsm { } else { section_prefix.into() }; + let fn_name = &sig.ident; // LSM probes need to return an integer corresponding to the correct // policy decision. Therefore we do not simply default to a return value // of 0 as in other program types. - let fn_name = &sig.ident; quote! { #[unsafe(no_mangle)] #[unsafe(link_section = #section_name)] diff --git a/aya-ebpf-macros/src/lsm_cgroup.rs b/aya-ebpf-macros/src/lsm_cgroup.rs new file mode 100644 index 00000000..97427b52 --- /dev/null +++ b/aya-ebpf-macros/src/lsm_cgroup.rs @@ -0,0 +1,87 @@ +use std::borrow::Cow; + +use proc_macro2::TokenStream; +use quote::quote; +use syn::{ItemFn, Result}; + +use crate::args::{err_on_unknown_args, pop_string_arg}; + +pub(crate) struct LsmCgroup { + item: ItemFn, + hook: Option, +} + +impl LsmCgroup { + pub(crate) fn parse(attrs: TokenStream, item: TokenStream) -> Result { + let item = syn::parse2(item)?; + let mut args = syn::parse2(attrs)?; + let hook = pop_string_arg(&mut args, "hook"); + err_on_unknown_args(&args)?; + + Ok(Self { item, hook }) + } + + pub(crate) fn expand(&self) -> TokenStream { + let Self { item, hook } = self; + let ItemFn { + attrs: _, + vis, + sig, + block: _, + } = item; + let section_prefix = "lsm_cgroup"; + let section_name: Cow<'_, _> = if let Some(name) = hook { + format!("{}/{}", section_prefix, name).into() + } else { + section_prefix.into() + }; + let fn_name = &sig.ident; + // LSM probes need to return an integer corresponding to the correct + // policy decision. Therefore we do not simply default to a return value + // of 0 as in other program types. + quote! { + #[unsafe(no_mangle)] + #[unsafe(link_section = #section_name)] + #vis fn #fn_name(ctx: *mut ::core::ffi::c_void) -> i32 { + return #fn_name(::aya_ebpf::programs::LsmContext::new(ctx)); + + #item + } + } + } +} + +#[cfg(test)] +mod tests { + use syn::parse_quote; + + use super::*; + + #[test] + fn test_lsm_cgroup() { + let prog = LsmCgroup::parse( + parse_quote! { + hook = "bprm_committed_creds", + }, + parse_quote! { + fn bprm_committed_creds(ctx: &mut ::aya_ebpf::programs::LsmContext) -> i32 { + 0 + } + }, + ) + .unwrap(); + let expanded = prog.expand(); + let expected = quote! { + #[unsafe(no_mangle)] + #[unsafe(link_section = "lsm_cgroup/bprm_committed_creds")] + fn bprm_committed_creds(ctx: *mut ::core::ffi::c_void) -> i32 { + return bprm_committed_creds(::aya_ebpf::programs::LsmContext::new(ctx)); + + fn bprm_committed_creds(ctx: &mut ::aya_ebpf::programs::LsmContext) -> i32 { + 0 + } + } + }; + assert_eq!(expected.to_string(), expanded.to_string()); + } +} diff --git a/aya-obj/src/obj.rs b/aya-obj/src/obj.rs index 871e6937..67861e46 100644 --- a/aya-obj/src/obj.rs +++ b/aya-obj/src/obj.rs @@ -274,6 +274,7 @@ pub enum ProgramSection { Lsm { sleepable: bool, }, + LsmCgroup, BtfTracePoint, FEntry { sleepable: bool, @@ -436,6 +437,7 @@ impl FromStr for ProgramSection { "raw_tp" | "raw_tracepoint" => RawTracePoint, "lsm" => Lsm { sleepable: false }, "lsm.s" => Lsm { sleepable: true }, + "lsm_cgroup" => LsmCgroup, "fentry" => FEntry { sleepable: false }, "fentry.s" => FEntry { sleepable: true }, "fexit" => FExit { sleepable: false }, @@ -2187,10 +2189,7 @@ mod tests { assert_matches!( obj.programs.get("foo"), Some(Program { - section: ProgramSection::Lsm { - sleepable: false, - .. - }, + section: ProgramSection::Lsm { sleepable: false }, .. }) ); @@ -2222,6 +2221,29 @@ mod tests { ); } + #[test] + fn test_parse_section_lsm_cgroup() { + let mut obj = fake_obj(); + fake_sym(&mut obj, 0, 0, "foo", FAKE_INS_LEN); + + assert_matches!( + obj.parse_section(fake_section( + EbpfSectionKind::Program, + "lsm_cgroup/foo", + bytes_of(&fake_ins()), + None + )), + Ok(()) + ); + assert_matches!( + obj.programs.get("foo"), + Some(Program { + section: ProgramSection::LsmCgroup, + .. + }) + ); + } + #[test] fn test_parse_section_btf_tracepoint() { let mut obj = fake_obj(); diff --git a/aya/src/bpf.rs b/aya/src/bpf.rs index 9c11defc..81d449da 100644 --- a/aya/src/bpf.rs +++ b/aya/src/bpf.rs @@ -24,9 +24,9 @@ use crate::{ programs::{ BtfTracePoint, CgroupDevice, CgroupSkb, CgroupSkbAttachType, CgroupSock, CgroupSockAddr, CgroupSockopt, CgroupSysctl, Extension, FEntry, FExit, FlowDissector, Iter, KProbe, - LircMode2, Lsm, PerfEvent, ProbeKind, Program, ProgramData, ProgramError, RawTracePoint, - SchedClassifier, SkLookup, SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, TracePoint, - UProbe, Xdp, + LircMode2, Lsm, LsmCgroup, PerfEvent, ProbeKind, Program, ProgramData, ProgramError, + RawTracePoint, SchedClassifier, SkLookup, SkMsg, SkSkb, SkSkbKind, SockOps, SocketFilter, + TracePoint, UProbe, Xdp, }, sys::{ bpf_load_btf, is_bpf_cookie_supported, is_bpf_global_data_supported, @@ -402,6 +402,7 @@ impl<'a> EbpfLoader<'a> { | ProgramSection::FEntry { sleepable: _ } | ProgramSection::FExit { sleepable: _ } | ProgramSection::Lsm { sleepable: _ } + | ProgramSection::LsmCgroup | ProgramSection::BtfTracePoint | ProgramSection::Iter { sleepable: _ } => { return Err(EbpfError::BtfError(err)); @@ -644,6 +645,9 @@ impl<'a> EbpfLoader<'a> { } Program::Lsm(Lsm { data }) } + ProgramSection::LsmCgroup => Program::LsmCgroup(LsmCgroup { + data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), + }), ProgramSection::BtfTracePoint => Program::BtfTracePoint(BtfTracePoint { data: ProgramData::new(prog_name, obj, btf_fd, *verifier_log_level), }), diff --git a/aya/src/programs/lsm_cgroup.rs b/aya/src/programs/lsm_cgroup.rs new file mode 100644 index 00000000..aee92883 --- /dev/null +++ b/aya/src/programs/lsm_cgroup.rs @@ -0,0 +1,108 @@ +//! LSM probes. + +use std::os::fd::AsFd; + +use aya_obj::{ + btf::{Btf, BtfKind}, + generated::{bpf_attach_type::BPF_LSM_CGROUP, bpf_prog_type::BPF_PROG_TYPE_LSM}, +}; + +use crate::{ + programs::{FdLink, FdLinkId, ProgramData, ProgramError, define_link_wrapper, load_program}, + sys::{BpfLinkCreateArgs, LinkTarget, SyscallError, bpf_link_create}, +}; + +/// A program that attaches to Linux LSM hooks with per-cgroup attachment type. Used to implement security policy and +/// audit logging. +/// +/// LSM probes can be attached to the kernel's [security hooks][1] 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`. +/// In order for the probes to fire, you also need the BPF LSM to be enabled through your +/// kernel's boot paramters (like `lsm=lockdown,yama,bpf`). +/// +/// # Minimum kernel version +/// +/// The minimum kernel version required to use this feature is 6.0. +/// +/// # Examples +/// +/// ```no_run +/// # #[derive(thiserror::Error, Debug)] +/// # enum LsmError { +/// # #[error(transparent)] +/// # BtfError(#[from] aya::BtfError), +/// # #[error(transparent)] +/// # Program(#[from] aya::programs::ProgramError), +/// # #[error(transparent)] +/// # Ebpf(#[from] aya::EbpfError), +/// # } +/// # let mut bpf = Ebpf::load_file("ebpf_programs.o")?; +/// use aya::{Ebpf, programs::LsmCgroup, BtfError, Btf}; +/// use std::fs::File; +/// +/// let btf = Btf::from_sys_fs()?; +/// let file = File::open("/sys/fs/cgroup/unified").unwrap(); +/// let program: &mut LsmCgroup = bpf.program_mut("lsm_prog").unwrap().try_into()?; +/// program.load("security_bprm_exec", &btf)?; +/// program.attach(file)?; +/// # Ok::<(), LsmError>(()) +/// ``` +/// +/// [1]: https://elixir.bootlin.com/linux/latest/source/include/linux/lsm_hook_defs.h +#[derive(Debug)] +#[doc(alias = "BPF_PROG_TYPE_LSM")] +pub struct LsmCgroup { + pub(crate) data: ProgramData, +} + +impl LsmCgroup { + /// Loads the program inside the kernel. + /// + /// # Arguments + /// + /// * `lsm_hook_name` - full name of the LSM hook that the program should + /// be attached to + pub fn load(&mut self, lsm_hook_name: &str, btf: &Btf) -> Result<(), ProgramError> { + self.data.expected_attach_type = Some(BPF_LSM_CGROUP); + let type_name = format!("bpf_lsm_{lsm_hook_name}"); + self.data.attach_btf_id = + Some(btf.id_by_type_name_kind(type_name.as_str(), BtfKind::Func)?); + load_program(BPF_PROG_TYPE_LSM, &mut self.data) + } + + /// Attaches the program. + /// + /// The returned value can be used to detach, see [LsmCgroup::detach]. + pub fn attach(&mut self, cgroup: T) -> Result { + let prog_fd = self.fd()?; + let prog_fd = prog_fd.as_fd(); + let cgroup_fd = cgroup.as_fd(); + let attach_type = self.data.expected_attach_type.unwrap(); + let btf_id = self.data.attach_btf_id.ok_or(ProgramError::NotLoaded)?; + let link_fd = bpf_link_create( + prog_fd, + LinkTarget::Fd(cgroup_fd), + attach_type, + 0, + Some(BpfLinkCreateArgs::TargetBtfId(btf_id)), + ) + .map_err(|io_error| SyscallError { + call: "bpf_link_create", + io_error, + })?; + + self.data.links.insert(LsmLink::new(FdLink::new(link_fd))) + } +} + +define_link_wrapper!( + /// The link used by [LsmCgroup] programs. + LsmLink, + /// The type returned by [LsmCgroup::attach]. Can be passed to [LsmCgroup::detach]. + LsmLinkId, + FdLink, + FdLinkId, + LsmCgroup, +); diff --git a/aya/src/programs/mod.rs b/aya/src/programs/mod.rs index c975c747..321dfa8a 100644 --- a/aya/src/programs/mod.rs +++ b/aya/src/programs/mod.rs @@ -57,6 +57,7 @@ pub mod kprobe; pub mod links; pub mod lirc_mode2; pub mod lsm; +pub mod lsm_cgroup; pub mod perf_attach; pub mod perf_event; pub mod raw_trace_point; @@ -109,6 +110,7 @@ pub use crate::programs::{ links::{CgroupAttachMode, Link, LinkOrder}, lirc_mode2::LircMode2, lsm::Lsm, + lsm_cgroup::LsmCgroup, perf_event::{PerfEvent, PerfEventScope, PerfTypeId, SamplePolicy}, probe::ProbeKind, raw_trace_point::RawTracePoint, @@ -308,6 +310,8 @@ pub enum Program { RawTracePoint(RawTracePoint), /// A [`Lsm`] program Lsm(Lsm), + /// A [`LsmCgroup`] program + LsmCgroup(LsmCgroup), /// A [`BtfTracePoint`] program BtfTracePoint(BtfTracePoint), /// A [`FEntry`] program @@ -332,32 +336,40 @@ impl Program { /// Returns the program type. pub fn prog_type(&self) -> ProgramType { match self { - Self::KProbe(_) => KProbe::PROGRAM_TYPE, - Self::UProbe(_) => UProbe::PROGRAM_TYPE, - Self::TracePoint(_) => TracePoint::PROGRAM_TYPE, - Self::SocketFilter(_) => SocketFilter::PROGRAM_TYPE, - Self::Xdp(_) => Xdp::PROGRAM_TYPE, - Self::SkMsg(_) => SkMsg::PROGRAM_TYPE, - Self::SkSkb(_) => SkSkb::PROGRAM_TYPE, - Self::SockOps(_) => SockOps::PROGRAM_TYPE, - Self::SchedClassifier(_) => SchedClassifier::PROGRAM_TYPE, - Self::CgroupSkb(_) => CgroupSkb::PROGRAM_TYPE, - Self::CgroupSysctl(_) => CgroupSysctl::PROGRAM_TYPE, - Self::CgroupSockopt(_) => CgroupSockopt::PROGRAM_TYPE, - Self::LircMode2(_) => LircMode2::PROGRAM_TYPE, - Self::PerfEvent(_) => PerfEvent::PROGRAM_TYPE, - Self::RawTracePoint(_) => RawTracePoint::PROGRAM_TYPE, - Self::Lsm(_) => Lsm::PROGRAM_TYPE, - Self::BtfTracePoint(_) => BtfTracePoint::PROGRAM_TYPE, - Self::FEntry(_) => FEntry::PROGRAM_TYPE, - Self::FExit(_) => FExit::PROGRAM_TYPE, - Self::Extension(_) => Extension::PROGRAM_TYPE, - Self::CgroupSockAddr(_) => CgroupSockAddr::PROGRAM_TYPE, - Self::SkLookup(_) => SkLookup::PROGRAM_TYPE, - Self::CgroupSock(_) => CgroupSock::PROGRAM_TYPE, - Self::CgroupDevice(_) => CgroupDevice::PROGRAM_TYPE, - Self::Iter(_) => Iter::PROGRAM_TYPE, - Self::FlowDissector(_) => FlowDissector::PROGRAM_TYPE, + Self::KProbe(_) | Self::UProbe(_) => ProgramType::KProbe, + Self::TracePoint(_) => ProgramType::TracePoint, + Self::SocketFilter(_) => ProgramType::SocketFilter, + Self::Xdp(_) => ProgramType::Xdp, + Self::SkMsg(_) => ProgramType::SkMsg, + Self::SkSkb(_) => ProgramType::SkSkb, + Self::SockOps(_) => ProgramType::SockOps, + Self::SchedClassifier(_) => ProgramType::SchedClassifier, + Self::CgroupSkb(_) => ProgramType::CgroupSkb, + Self::CgroupSysctl(_) => ProgramType::CgroupSysctl, + Self::CgroupSockopt(_) => ProgramType::CgroupSockopt, + Self::LircMode2(_) => ProgramType::LircMode2, + Self::PerfEvent(_) => ProgramType::PerfEvent, + Self::RawTracePoint(_) => ProgramType::RawTracePoint, + Self::Lsm(_) => ProgramType::Lsm, + Self::LsmCgroup(_) => ProgramType::Lsm, + // The following program types are a subset of `TRACING` programs: + // + // - `BPF_TRACE_RAW_TP` (`BtfTracePoint`) + // - `BTF_TRACE_FENTRY` (`FEntry`) + // - `BPF_MODIFY_RETURN` (not supported yet in Aya) + // - `BPF_TRACE_FEXIT` (`FExit`) + // - `BPF_TRACE_ITER` (`Iter`) + // + // https://github.com/torvalds/linux/blob/v6.12/kernel/bpf/syscall.c#L3935-L3940 + Self::BtfTracePoint(_) | Self::FEntry(_) | Self::FExit(_) | Self::Iter(_) => { + ProgramType::Tracing + } + Self::Extension(_) => ProgramType::Extension, + Self::CgroupSockAddr(_) => ProgramType::CgroupSockAddr, + Self::SkLookup(_) => ProgramType::SkLookup, + Self::CgroupSock(_) => ProgramType::CgroupSock, + Self::CgroupDevice(_) => ProgramType::CgroupDevice, + Self::FlowDissector(_) => ProgramType::FlowDissector, } } @@ -380,6 +392,7 @@ impl Program { Self::PerfEvent(p) => p.pin(path), Self::RawTracePoint(p) => p.pin(path), Self::Lsm(p) => p.pin(path), + Self::LsmCgroup(p) => p.pin(path), Self::BtfTracePoint(p) => p.pin(path), Self::FEntry(p) => p.pin(path), Self::FExit(p) => p.pin(path), @@ -412,6 +425,7 @@ impl Program { Self::PerfEvent(mut p) => p.unload(), Self::RawTracePoint(mut p) => p.unload(), Self::Lsm(mut p) => p.unload(), + Self::LsmCgroup(mut p) => p.unload(), Self::BtfTracePoint(mut p) => p.unload(), Self::FEntry(mut p) => p.unload(), Self::FExit(mut p) => p.unload(), @@ -446,6 +460,7 @@ impl Program { Self::PerfEvent(p) => p.fd(), Self::RawTracePoint(p) => p.fd(), Self::Lsm(p) => p.fd(), + Self::LsmCgroup(p) => p.fd(), Self::BtfTracePoint(p) => p.fd(), Self::FEntry(p) => p.fd(), Self::FExit(p) => p.fd(), @@ -481,6 +496,7 @@ impl Program { Self::PerfEvent(p) => p.info(), Self::RawTracePoint(p) => p.info(), Self::Lsm(p) => p.info(), + Self::LsmCgroup(p) => p.info(), Self::BtfTracePoint(p) => p.info(), Self::FEntry(p) => p.info(), Self::FExit(p) => p.info(), @@ -795,6 +811,7 @@ impl_program_unload!( LircMode2, PerfEvent, Lsm, + LsmCgroup, RawTracePoint, BtfTracePoint, FEntry, @@ -837,6 +854,7 @@ impl_fd!( LircMode2, PerfEvent, Lsm, + LsmCgroup, RawTracePoint, BtfTracePoint, FEntry, @@ -944,6 +962,7 @@ impl_program_pin!( LircMode2, PerfEvent, Lsm, + LsmCgroup, RawTracePoint, BtfTracePoint, FEntry, @@ -984,8 +1003,9 @@ impl_from_pin!( SkMsg, CgroupSysctl, LircMode2, - PerfEvent, Lsm, + LsmCgroup, + PerfEvent, RawTracePoint, BtfTracePoint, FEntry, @@ -1150,6 +1170,7 @@ impl_try_from_program!( LircMode2, PerfEvent, Lsm, + LsmCgroup, RawTracePoint, BtfTracePoint, FEntry, @@ -1178,6 +1199,7 @@ impl_info!( LircMode2, PerfEvent, Lsm, + LsmCgroup, RawTracePoint, BtfTracePoint, FEntry, diff --git a/test-distro/src/init.rs b/test-distro/src/init.rs index 7dd9d952..7582ba66 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: "cgroup2", + target: "/sys/fs/cgroup", + fstype: "cgroup2", + 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 2dc736d3..6665b2a7 100644 --- a/test/integration-ebpf/src/test.rs +++ b/test/integration-ebpf/src/test.rs @@ -3,9 +3,12 @@ use aya_ebpf::{ bindings::{bpf_ret_code, xdp_action}, - macros::{flow_dissector, kprobe, kretprobe, tracepoint, uprobe, uretprobe, xdp}, + macros::{ + flow_dissector, kprobe, kretprobe, lsm, lsm_cgroup, tracepoint, uprobe, uretprobe, xdp, + }, programs::{ - FlowDissectorContext, ProbeContext, RetProbeContext, TracePointContext, XdpContext, + FlowDissectorContext, LsmContext, ProbeContext, RetProbeContext, TracePointContext, + XdpContext, }, }; #[cfg(not(test))] @@ -54,3 +57,13 @@ pub fn test_flow(_ctx: FlowDissectorContext) -> u32 { // Linux kernel for inspiration. bpf_ret_code::BPF_FLOW_DISSECTOR_CONTINUE } + +#[lsm_cgroup(hook = "socket_bind")] +pub fn test_lsmcgroup(_ctx: LsmContext) -> i32 { + 0 +} + +#[lsm(hook = "socket_bind")] +pub fn test_lsm(_ctx: LsmContext) -> i32 { + -1 +} diff --git a/test/integration-test/src/tests.rs b/test/integration-test/src/tests.rs index 9ca83669..13d4ed9c 100644 --- a/test/integration-test/src/tests.rs +++ b/test/integration-test/src/tests.rs @@ -5,6 +5,7 @@ mod info; mod iter; mod load; mod log; +mod lsm; mod raw_tracepoint; mod rbpf; mod relocations; diff --git a/test/integration-test/src/tests/lsm.rs b/test/integration-test/src/tests/lsm.rs new file mode 100644 index 00000000..a73f0b4e --- /dev/null +++ b/test/integration-test/src/tests/lsm.rs @@ -0,0 +1,79 @@ +use std::{ + fs::{File, write}, + io::ErrorKind, + net::TcpListener, + path::Path, +}; + +use aya::{ + Btf, Ebpf, + programs::{Lsm, lsm_cgroup::LsmCgroup}, + util::KernelVersion, +}; +#[test] +//#[ignore = "LSM programs need a special kernel config, which is not supported by GitHub runners[waiting on PR: 1063]."] +fn lsm_cgroup() { + let kernel_version = KernelVersion::current().unwrap(); + if kernel_version < KernelVersion::new(6, 0, 0) { + eprintln!("skipping lsm_cgroup test on kernel {kernel_version:?}"); + return; + } + + let mut bpf: Ebpf = Ebpf::load(crate::TEST).unwrap(); + let prog: &mut LsmCgroup = bpf + .program_mut("test_lsmcgroup") + .unwrap() + .try_into() + .unwrap(); + let btf = Btf::from_sys_fs().expect("could not get btf from sys"); + prog.load("socket_bind", &btf).unwrap(); + + assert_matches::assert_matches!(TcpListener::bind("127.0.0.1:12345"), Ok(_)); + + let cgroup_dir = Path::new("/sys/fs/cgroup/lsm_cgroup_test"); + std::fs::create_dir_all(cgroup_dir).expect("could not create cgroup dir"); + + let proc_path = cgroup_dir.join("cgroup.procs"); + + let link_id = prog.attach(File::open(cgroup_dir).unwrap()).unwrap(); + let _guard = scopeguard::guard((), |()| { + prog.detach(link_id).unwrap(); + }); + + assert_matches::assert_matches!(TcpListener::bind("127.0.0.1:12345"), Ok(_)); + + let pid = std::process::id(); + write(&proc_path, format!("{}\n", pid)).expect("could not write into procs file"); + let _guard = scopeguard::guard((), |()| { + let path = Path::new("/sys/fs/cgroup/cgroup.procs"); + write(path, format!("{}\n", pid)).expect("could not write into procs file"); + write(&proc_path, "").expect("could not write into procs file"); + std::fs::remove_dir_all(cgroup_dir).unwrap(); + }); + + assert_matches::assert_matches!(TcpListener::bind("127.0.0.1:12345"), Err(e) => assert_eq!( + e.kind(), ErrorKind::PermissionDenied)); +} + +#[test] +//#[ignore = "LSM programs need a special kernel config, which is not supported by GitHub runners[waiting on PR: 1063]."] +fn lsm() { + let kernel_version = KernelVersion::current().unwrap(); + if kernel_version < KernelVersion::new(5, 7, 0) { + eprintln!("skipping lsm test on kernel {kernel_version:?}"); + return; + } + + let mut bpf: Ebpf = Ebpf::load(crate::TEST).unwrap(); + let prog: &mut Lsm = bpf.program_mut("test_lsm").unwrap().try_into().unwrap(); + let btf = Btf::from_sys_fs().expect("could not get btf from sys"); + prog.load("socket_bind", &btf).unwrap(); + + assert_matches::assert_matches!(TcpListener::bind("127.0.0.1:12345"), Ok(_)); + + prog.attach().unwrap(); + + assert_matches::assert_matches!(TcpListener::bind("127.0.0.1:12345"), Err(e) => assert_eq!( + e.kind(), ErrorKind::PermissionDenied) + ); +} diff --git a/xtask/public-api/aya-ebpf-macros.txt b/xtask/public-api/aya-ebpf-macros.txt index 484df241..a3729830 100644 --- a/xtask/public-api/aya-ebpf-macros.txt +++ b/xtask/public-api/aya-ebpf-macros.txt @@ -13,6 +13,7 @@ pub proc macro aya_ebpf_macros::#[flow_dissector] pub proc macro aya_ebpf_macros::#[kprobe] pub proc macro aya_ebpf_macros::#[kretprobe] pub proc macro aya_ebpf_macros::#[lsm] +pub proc macro aya_ebpf_macros::#[lsm_cgroup] pub proc macro aya_ebpf_macros::#[map] pub proc macro aya_ebpf_macros::#[perf_event] pub proc macro aya_ebpf_macros::#[raw_tracepoint] diff --git a/xtask/public-api/aya-obj.txt b/xtask/public-api/aya-obj.txt index 9fce242e..e0696754 100644 --- a/xtask/public-api/aya-obj.txt +++ b/xtask/public-api/aya-obj.txt @@ -8616,6 +8616,7 @@ pub aya_obj::obj::ProgramSection::KRetProbe pub aya_obj::obj::ProgramSection::LircMode2 pub aya_obj::obj::ProgramSection::Lsm pub aya_obj::obj::ProgramSection::Lsm::sleepable: bool +pub aya_obj::obj::ProgramSection::LsmCgroup pub aya_obj::obj::ProgramSection::PerfEvent pub aya_obj::obj::ProgramSection::RawTracePoint pub aya_obj::obj::ProgramSection::SchedClassifier @@ -9479,6 +9480,7 @@ pub aya_obj::ProgramSection::KRetProbe pub aya_obj::ProgramSection::LircMode2 pub aya_obj::ProgramSection::Lsm pub aya_obj::ProgramSection::Lsm::sleepable: bool +pub aya_obj::ProgramSection::LsmCgroup pub aya_obj::ProgramSection::PerfEvent pub aya_obj::ProgramSection::RawTracePoint pub aya_obj::ProgramSection::SchedClassifier diff --git a/xtask/public-api/aya.txt b/xtask/public-api/aya.txt index 94a70d3c..a93168eb 100644 --- a/xtask/public-api/aya.txt +++ b/xtask/public-api/aya.txt @@ -4328,6 +4328,8 @@ impl core::convert::From for aya::programs::fexit: pub fn aya::programs::fexit::FExitLink::from(b: aya::programs::links::FdLink) -> aya::programs::fexit::FExitLink impl core::convert::From for aya::programs::lsm::LsmLink pub fn aya::programs::lsm::LsmLink::from(b: aya::programs::links::FdLink) -> aya::programs::lsm::LsmLink +impl core::convert::From for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::from(b: aya::programs::links::FdLink) -> aya::programs::lsm_cgroup::LsmLink impl core::convert::From for aya::programs::raw_trace_point::RawTracePointLink pub fn aya::programs::raw_trace_point::RawTracePointLink::from(b: aya::programs::links::FdLink) -> aya::programs::raw_trace_point::RawTracePointLink impl core::convert::From for aya::programs::sk_lookup::SkLookupLink @@ -4338,6 +4340,8 @@ impl core::convert::From for aya::programs::li pub fn aya::programs::links::FdLink::from(p: aya::programs::links::PinnedLink) -> Self impl core::convert::From for aya::programs::links::FdLink pub fn aya::programs::links::FdLink::from(w: aya::programs::lsm::LsmLink) -> aya::programs::links::FdLink +impl core::convert::From for aya::programs::links::FdLink +pub fn aya::programs::links::FdLink::from(w: aya::programs::lsm_cgroup::LsmLink) -> aya::programs::links::FdLink impl core::convert::From for aya::programs::links::FdLink pub fn aya::programs::links::FdLink::from(w: aya::programs::raw_trace_point::RawTracePointLink) -> aya::programs::links::FdLink impl core::convert::From for aya::programs::links::FdLink @@ -4669,6 +4673,10 @@ impl aya::programs::links::Link for aya::programs::lsm::LsmLink pub type aya::programs::lsm::LsmLink::Id = aya::programs::lsm::LsmLinkId pub fn aya::programs::lsm::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::lsm::LsmLink::id(&self) -> Self::Id +impl aya::programs::links::Link for aya::programs::lsm_cgroup::LsmLink +pub type aya::programs::lsm_cgroup::LsmLink::Id = aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::lsm_cgroup::LsmLink::id(&self) -> Self::Id impl aya::programs::links::Link for aya::programs::perf_attach::PerfLink pub type aya::programs::perf_attach::PerfLink::Id = aya::programs::perf_attach::PerfLinkId pub fn aya::programs::perf_attach::PerfLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> @@ -4983,6 +4991,136 @@ impl core::borrow::BorrowMut for aya::programs::lsm::LsmLinkId where T: ?c pub fn aya::programs::lsm::LsmLinkId::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::lsm::LsmLinkId pub fn aya::programs::lsm::LsmLinkId::from(t: T) -> T +pub mod aya::programs::lsm_cgroup +pub struct aya::programs::lsm_cgroup::LsmCgroup +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::attach(&mut self, cgroup: T) -> core::result::Result +pub fn aya::programs::lsm_cgroup::LsmCgroup::load(&mut self, lsm_hook_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError> +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::detach(&mut self, link_id: aya::programs::lsm_cgroup::LsmLinkId) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::lsm_cgroup::LsmCgroup::take_link(&mut self, link_id: aya::programs::lsm_cgroup::LsmLinkId) -> core::result::Result +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError> +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::from_pin>(path: P) -> core::result::Result +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::info(&self) -> core::result::Result +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +pub fn aya::programs::lsm_cgroup::LsmCgroup::unpin(self) -> core::result::Result<(), std::io::error::Error> +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError> +impl core::fmt::Debug for aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::ops::drop::Drop for aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::drop(&mut self) +impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::lsm_cgroup::LsmCgroup +pub type &'a aya::programs::lsm_cgroup::LsmCgroup::Error = aya::programs::ProgramError +pub fn &'a aya::programs::lsm_cgroup::LsmCgroup::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::lsm_cgroup::LsmCgroup, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::lsm_cgroup::LsmCgroup +pub type &'a mut aya::programs::lsm_cgroup::LsmCgroup::Error = aya::programs::ProgramError +pub fn &'a mut aya::programs::lsm_cgroup::LsmCgroup::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::lsm_cgroup::LsmCgroup, aya::programs::ProgramError> +impl core::marker::Freeze for aya::programs::lsm_cgroup::LsmCgroup +impl core::marker::Send for aya::programs::lsm_cgroup::LsmCgroup +impl core::marker::Sync for aya::programs::lsm_cgroup::LsmCgroup +impl core::marker::Unpin for aya::programs::lsm_cgroup::LsmCgroup +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::lsm_cgroup::LsmCgroup +impl core::panic::unwind_safe::UnwindSafe for aya::programs::lsm_cgroup::LsmCgroup +impl core::convert::Into for aya::programs::lsm_cgroup::LsmCgroup where U: core::convert::From +pub fn aya::programs::lsm_cgroup::LsmCgroup::into(self) -> U +impl core::convert::TryFrom for aya::programs::lsm_cgroup::LsmCgroup where U: core::convert::Into +pub type aya::programs::lsm_cgroup::LsmCgroup::Error = core::convert::Infallible +pub fn aya::programs::lsm_cgroup::LsmCgroup::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::lsm_cgroup::LsmCgroup where U: core::convert::TryFrom +pub type aya::programs::lsm_cgroup::LsmCgroup::Error = >::Error +pub fn aya::programs::lsm_cgroup::LsmCgroup::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::lsm_cgroup::LsmCgroup where T: 'static + ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmCgroup::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::lsm_cgroup::LsmCgroup where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmCgroup::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::lsm_cgroup::LsmCgroup where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmCgroup::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::from(t: T) -> T +pub struct aya::programs::lsm_cgroup::LsmLink(_) +impl aya::programs::links::Link for aya::programs::lsm_cgroup::LsmLink +pub type aya::programs::lsm_cgroup::LsmLink::Id = aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::lsm_cgroup::LsmLink::id(&self) -> Self::Id +impl core::cmp::Eq for aya::programs::lsm_cgroup::LsmLink +impl core::cmp::PartialEq for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::eq(&self, other: &Self) -> bool +impl core::convert::From for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::from(b: aya::programs::links::FdLink) -> aya::programs::lsm_cgroup::LsmLink +impl core::convert::From for aya::programs::links::FdLink +pub fn aya::programs::links::FdLink::from(w: aya::programs::lsm_cgroup::LsmLink) -> aya::programs::links::FdLink +impl core::fmt::Debug for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::hash::Hash for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::hash(&self, state: &mut H) +impl core::ops::drop::Drop for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::drop(&mut self) +impl equivalent::Equivalent for aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLinkId::equivalent(&self, key: &aya::programs::lsm_cgroup::LsmLink) -> bool +impl core::marker::Freeze for aya::programs::lsm_cgroup::LsmLink +impl core::marker::Send for aya::programs::lsm_cgroup::LsmLink +impl core::marker::Sync for aya::programs::lsm_cgroup::LsmLink +impl core::marker::Unpin for aya::programs::lsm_cgroup::LsmLink +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::lsm_cgroup::LsmLink +impl core::panic::unwind_safe::UnwindSafe for aya::programs::lsm_cgroup::LsmLink +impl equivalent::Equivalent for aya::programs::lsm_cgroup::LsmLink where Q: core::cmp::Eq + ?core::marker::Sized, K: core::borrow::Borrow + ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLink::equivalent(&self, key: &K) -> bool +impl core::convert::Into for aya::programs::lsm_cgroup::LsmLink where U: core::convert::From +pub fn aya::programs::lsm_cgroup::LsmLink::into(self) -> U +impl core::convert::TryFrom for aya::programs::lsm_cgroup::LsmLink where U: core::convert::Into +pub type aya::programs::lsm_cgroup::LsmLink::Error = core::convert::Infallible +pub fn aya::programs::lsm_cgroup::LsmLink::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::lsm_cgroup::LsmLink where U: core::convert::TryFrom +pub type aya::programs::lsm_cgroup::LsmLink::Error = >::Error +pub fn aya::programs::lsm_cgroup::LsmLink::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::lsm_cgroup::LsmLink where T: 'static + ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLink::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::lsm_cgroup::LsmLink where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLink::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::lsm_cgroup::LsmLink where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLink::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::lsm_cgroup::LsmLink +pub fn aya::programs::lsm_cgroup::LsmLink::from(t: T) -> T +pub struct aya::programs::lsm_cgroup::LsmLinkId(_) +impl core::cmp::Eq for aya::programs::lsm_cgroup::LsmLinkId +impl core::cmp::PartialEq for aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLinkId::eq(&self, other: &aya::programs::lsm_cgroup::LsmLinkId) -> bool +impl core::fmt::Debug for aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLinkId::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::hash::Hash for aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLinkId::hash<__H: core::hash::Hasher>(&self, state: &mut __H) +impl core::marker::StructuralPartialEq for aya::programs::lsm_cgroup::LsmLinkId +impl equivalent::Equivalent for aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLinkId::equivalent(&self, key: &aya::programs::lsm_cgroup::LsmLink) -> bool +impl core::marker::Freeze for aya::programs::lsm_cgroup::LsmLinkId +impl core::marker::Send for aya::programs::lsm_cgroup::LsmLinkId +impl core::marker::Sync for aya::programs::lsm_cgroup::LsmLinkId +impl core::marker::Unpin for aya::programs::lsm_cgroup::LsmLinkId +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::lsm_cgroup::LsmLinkId +impl core::panic::unwind_safe::UnwindSafe for aya::programs::lsm_cgroup::LsmLinkId +impl equivalent::Equivalent for aya::programs::lsm_cgroup::LsmLinkId where Q: core::cmp::Eq + ?core::marker::Sized, K: core::borrow::Borrow + ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLinkId::equivalent(&self, key: &K) -> bool +impl core::convert::Into for aya::programs::lsm_cgroup::LsmLinkId where U: core::convert::From +pub fn aya::programs::lsm_cgroup::LsmLinkId::into(self) -> U +impl core::convert::TryFrom for aya::programs::lsm_cgroup::LsmLinkId where U: core::convert::Into +pub type aya::programs::lsm_cgroup::LsmLinkId::Error = core::convert::Infallible +pub fn aya::programs::lsm_cgroup::LsmLinkId::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::lsm_cgroup::LsmLinkId where U: core::convert::TryFrom +pub type aya::programs::lsm_cgroup::LsmLinkId::Error = >::Error +pub fn aya::programs::lsm_cgroup::LsmLinkId::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::lsm_cgroup::LsmLinkId where T: 'static + ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLinkId::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::lsm_cgroup::LsmLinkId where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLinkId::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::lsm_cgroup::LsmLinkId where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmLinkId::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLinkId::from(t: T) -> T pub mod aya::programs::perf_attach pub struct aya::programs::perf_attach::PerfLink impl aya::programs::links::Link for aya::programs::perf_attach::PerfLink @@ -7588,6 +7726,7 @@ pub aya::programs::Program::Iter(aya::programs::iter::Iter) pub aya::programs::Program::KProbe(aya::programs::kprobe::KProbe) pub aya::programs::Program::LircMode2(aya::programs::lirc_mode2::LircMode2) pub aya::programs::Program::Lsm(aya::programs::lsm::Lsm) +pub aya::programs::Program::LsmCgroup(aya::programs::lsm_cgroup::LsmCgroup) pub aya::programs::Program::PerfEvent(aya::programs::perf_event::PerfEvent) pub aya::programs::Program::RawTracePoint(aya::programs::raw_trace_point::RawTracePoint) pub aya::programs::Program::SchedClassifier(aya::programs::tc::SchedClassifier) @@ -7649,6 +7788,9 @@ pub fn &'a aya::programs::lirc_mode2::LircMode2::try_from(program: &'a aya::prog impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::lsm::Lsm pub type &'a aya::programs::lsm::Lsm::Error = aya::programs::ProgramError pub fn &'a aya::programs::lsm::Lsm::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::lsm::Lsm, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::lsm_cgroup::LsmCgroup +pub type &'a aya::programs::lsm_cgroup::LsmCgroup::Error = aya::programs::ProgramError +pub fn &'a aya::programs::lsm_cgroup::LsmCgroup::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::lsm_cgroup::LsmCgroup, aya::programs::ProgramError> impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::perf_event::PerfEvent pub type &'a aya::programs::perf_event::PerfEvent::Error = aya::programs::ProgramError pub fn &'a aya::programs::perf_event::PerfEvent::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::perf_event::PerfEvent, aya::programs::ProgramError> @@ -7727,6 +7869,9 @@ pub fn &'a mut aya::programs::lirc_mode2::LircMode2::try_from(program: &'a mut a impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::lsm::Lsm pub type &'a mut aya::programs::lsm::Lsm::Error = aya::programs::ProgramError pub fn &'a mut aya::programs::lsm::Lsm::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::lsm::Lsm, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::lsm_cgroup::LsmCgroup +pub type &'a mut aya::programs::lsm_cgroup::LsmCgroup::Error = aya::programs::ProgramError +pub fn &'a mut aya::programs::lsm_cgroup::LsmCgroup::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::lsm_cgroup::LsmCgroup, aya::programs::ProgramError> impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::perf_event::PerfEvent pub type &'a mut aya::programs::perf_event::PerfEvent::Error = aya::programs::ProgramError pub fn &'a mut aya::programs::perf_event::PerfEvent::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::perf_event::PerfEvent, aya::programs::ProgramError> @@ -9072,6 +9217,56 @@ impl core::borrow::BorrowMut for aya::programs::lsm::Lsm where T: ?core::m pub fn aya::programs::lsm::Lsm::borrow_mut(&mut self) -> &mut T impl core::convert::From for aya::programs::lsm::Lsm pub fn aya::programs::lsm::Lsm::from(t: T) -> T +pub struct aya::programs::LsmCgroup +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::attach(&mut self, cgroup: T) -> core::result::Result +pub fn aya::programs::lsm_cgroup::LsmCgroup::load(&mut self, lsm_hook_name: &str, btf: &aya_obj::btf::btf::Btf) -> core::result::Result<(), aya::programs::ProgramError> +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::detach(&mut self, link_id: aya::programs::lsm_cgroup::LsmLinkId) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::lsm_cgroup::LsmCgroup::take_link(&mut self, link_id: aya::programs::lsm_cgroup::LsmLinkId) -> core::result::Result +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::fd(&self) -> core::result::Result<&aya::programs::ProgramFd, aya::programs::ProgramError> +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::from_pin>(path: P) -> core::result::Result +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::info(&self) -> core::result::Result +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::pin>(&mut self, path: P) -> core::result::Result<(), aya::pin::PinError> +pub fn aya::programs::lsm_cgroup::LsmCgroup::unpin(self) -> core::result::Result<(), std::io::error::Error> +impl aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::unload(&mut self) -> core::result::Result<(), aya::programs::ProgramError> +impl core::fmt::Debug for aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +impl core::ops::drop::Drop for aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::drop(&mut self) +impl<'a> core::convert::TryFrom<&'a aya::programs::Program> for &'a aya::programs::lsm_cgroup::LsmCgroup +pub type &'a aya::programs::lsm_cgroup::LsmCgroup::Error = aya::programs::ProgramError +pub fn &'a aya::programs::lsm_cgroup::LsmCgroup::try_from(program: &'a aya::programs::Program) -> core::result::Result<&'a aya::programs::lsm_cgroup::LsmCgroup, aya::programs::ProgramError> +impl<'a> core::convert::TryFrom<&'a mut aya::programs::Program> for &'a mut aya::programs::lsm_cgroup::LsmCgroup +pub type &'a mut aya::programs::lsm_cgroup::LsmCgroup::Error = aya::programs::ProgramError +pub fn &'a mut aya::programs::lsm_cgroup::LsmCgroup::try_from(program: &'a mut aya::programs::Program) -> core::result::Result<&'a mut aya::programs::lsm_cgroup::LsmCgroup, aya::programs::ProgramError> +impl core::marker::Freeze for aya::programs::lsm_cgroup::LsmCgroup +impl core::marker::Send for aya::programs::lsm_cgroup::LsmCgroup +impl core::marker::Sync for aya::programs::lsm_cgroup::LsmCgroup +impl core::marker::Unpin for aya::programs::lsm_cgroup::LsmCgroup +impl core::panic::unwind_safe::RefUnwindSafe for aya::programs::lsm_cgroup::LsmCgroup +impl core::panic::unwind_safe::UnwindSafe for aya::programs::lsm_cgroup::LsmCgroup +impl core::convert::Into for aya::programs::lsm_cgroup::LsmCgroup where U: core::convert::From +pub fn aya::programs::lsm_cgroup::LsmCgroup::into(self) -> U +impl core::convert::TryFrom for aya::programs::lsm_cgroup::LsmCgroup where U: core::convert::Into +pub type aya::programs::lsm_cgroup::LsmCgroup::Error = core::convert::Infallible +pub fn aya::programs::lsm_cgroup::LsmCgroup::try_from(value: U) -> core::result::Result>::Error> +impl core::convert::TryInto for aya::programs::lsm_cgroup::LsmCgroup where U: core::convert::TryFrom +pub type aya::programs::lsm_cgroup::LsmCgroup::Error = >::Error +pub fn aya::programs::lsm_cgroup::LsmCgroup::try_into(self) -> core::result::Result>::Error> +impl core::any::Any for aya::programs::lsm_cgroup::LsmCgroup where T: 'static + ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmCgroup::type_id(&self) -> core::any::TypeId +impl core::borrow::Borrow for aya::programs::lsm_cgroup::LsmCgroup where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmCgroup::borrow(&self) -> &T +impl core::borrow::BorrowMut for aya::programs::lsm_cgroup::LsmCgroup where T: ?core::marker::Sized +pub fn aya::programs::lsm_cgroup::LsmCgroup::borrow_mut(&mut self) -> &mut T +impl core::convert::From for aya::programs::lsm_cgroup::LsmCgroup +pub fn aya::programs::lsm_cgroup::LsmCgroup::from(t: T) -> T pub struct aya::programs::PerfEvent impl aya::programs::perf_event::PerfEvent pub const aya::programs::perf_event::PerfEvent::PROGRAM_TYPE: aya::programs::ProgramType @@ -9935,6 +10130,10 @@ impl aya::programs::links::Link for aya::programs::lsm::LsmLink pub type aya::programs::lsm::LsmLink::Id = aya::programs::lsm::LsmLinkId pub fn aya::programs::lsm::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> pub fn aya::programs::lsm::LsmLink::id(&self) -> Self::Id +impl aya::programs::links::Link for aya::programs::lsm_cgroup::LsmLink +pub type aya::programs::lsm_cgroup::LsmLink::Id = aya::programs::lsm_cgroup::LsmLinkId +pub fn aya::programs::lsm_cgroup::LsmLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> +pub fn aya::programs::lsm_cgroup::LsmLink::id(&self) -> Self::Id impl aya::programs::links::Link for aya::programs::perf_attach::PerfLink pub type aya::programs::perf_attach::PerfLink::Id = aya::programs::perf_attach::PerfLinkId pub fn aya::programs::perf_attach::PerfLink::detach(self) -> core::result::Result<(), aya::programs::ProgramError> diff --git a/xtask/src/run.rs b/xtask/src/run.rs index 187828f9..cc315ee0 100644 --- a/xtask/src/run.rs +++ b/xtask/src/run.rs @@ -498,6 +498,8 @@ pub fn run(opts: Options) -> Result<()> { // // Heed the advice and boot with noapic. We don't know why this happens. kernel_args.push(" noapic"); + // We need to enable LSM bpf to be able to run LSM integration tests. + kernel_args.push(" lsm=lockdown,capability,bpf"); qemu.args(["-no-reboot", "-nographic", "-m", "512M", "-smp", "2"]) .arg("-append") .arg(kernel_args)