#![no_std]#![no_main]useaya_ebpf::{cty::c_int,macros::lsm,programs::LsmContext};useaya_log_ebpf::info;// (1)#[allow(non_upper_case_globals)]#[allow(non_snake_case)]#[allow(non_camel_case_types)]#[allow(dead_code)]modvmlinux;usevmlinux::task_struct;// (2)/// PID of the process for which setting a negative nice value is denied.#[no_mangle]staticPID: i32=0;#[lsm(hook = "task_setnice")]pubfntask_setnice(ctx: LsmContext)-> i32{matchunsafe{try_task_setnice(ctx)}{Ok(ret)=>ret,Err(ret)=>ret,}}// (3)unsafefntry_task_setnice(ctx: LsmContext)-> Result<i32,i32>{letp: *consttask_struct=ctx.arg(0);letnice: c_int=ctx.arg(1);letret: c_int=ctx.arg(2);letglobal_pid: c_int=core::ptr::read_volatile(&PID);letpid: c_int=(*p).pid;info!(&ctx,"The PID supplied to this program is: {}, with nice value {} and return value {}. Monitoring for changes in PID: {}",pid,nice,ret,global_pid);ifret!=0{returnErr(ret);}ifpid==global_pid&&nice<0{returnErr(-1);}Ok(0)}#[panic_handler]fnpanic(_info: &core::panic::PanicInfo)-> !{unsafe{core::hint::unreachable_unchecked()}}
usestd::process;useaya::{include_bytes_aligned,programs::Lsm,BpfLoader,Btf};useaya_log::BpfLogger;uselog::{info,warn};usetokio::signal;#[tokio::main]asyncfnmain()-> Result<(),anyhow::Error>{env_logger::init();// (1)letpid=process::id()asi32;info!("PID: {}",pid);// This will include your eBPF object file as raw bytes at compile-time and load it at// runtime. This approach is recommended for most real-world use cases. If you would// like to specify the eBPF program at runtime rather than at compile-time, you can// reach for `Bpf::load_file` instead.#[cfg(debug_assertions)]letmutbpf=BpfLoader::new().set_global("PID",&pid,true).load(include_bytes_aligned!("../../target/bpfel-unknown-none/debug/lsm-nice"),)?;#[cfg(not(debug_assertions))]letmutbpf=BpfLoader::new().set_global("PID",&pid,true).load(include_bytes_aligned!("../../target/bpfel-unknown-none/release/lsm-nice"),)?;ifletErr(e)=BpfLogger::init(&mutbpf){// This can happen if you remove all log statements from your eBPF program.warn!("failed to initialize eBPF logger: {}",e);}letbtf=Btf::from_sys_fs()?;letprogram: &mutLsm=bpf.program_mut("task_setnice").unwrap().try_into()?;program.load("task_setnice",&btf)?;program.attach()?;info!("Waiting for Ctrl-C...");signal::ctrl_c().await?;info!("Exiting...");Ok(())}