diff --git a/src/agent/Cargo.lock b/src/agent/Cargo.lock index d78770fd25..08ea024a68 100644 --- a/src/agent/Cargo.lock +++ b/src/agent/Cargo.lock @@ -1341,6 +1341,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac" +[[package]] +name = "rlimit" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e7148757b4951f04391d2b301b2e3597d504c4d2434212d542b73c1a6b3f847" +dependencies = [ + "libc", +] + [[package]] name = "rtnetlink" version = "0.6.0" @@ -1403,6 +1412,7 @@ dependencies = [ "protobuf", "protocols", "regex", + "rlimit", "scan_fmt", "scopeguard", "serde", diff --git a/src/agent/rustjail/Cargo.toml b/src/agent/rustjail/Cargo.toml index 5fd406d09e..74e52de064 100644 --- a/src/agent/rustjail/Cargo.toml +++ b/src/agent/rustjail/Cargo.toml @@ -26,6 +26,7 @@ dirs = "3.0.1" anyhow = "1.0.32" cgroups = { package = "cgroups-rs", version = "0.2.1" } tempfile = "3.1.0" +rlimit = "0.5.3" tokio = { version = "0.2", features = ["sync", "io-util", "process", "time", "macros"] } futures = "0.3" diff --git a/src/agent/rustjail/src/container.rs b/src/agent/rustjail/src/container.rs index 3948b5ec22..20067d958c 100644 --- a/src/agent/rustjail/src/container.rs +++ b/src/agent/rustjail/src/container.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, Context, Result}; use libc::pid_t; -use oci::{Hook, Linux, LinuxNamespace, LinuxResources, POSIXRlimit, Spec}; +use oci::{Hook, Linux, LinuxNamespace, LinuxResources, Spec}; use oci::{LinuxDevice, LinuxIDMapping}; use std::clone::Clone; use std::ffi::{CStr, CString}; @@ -48,6 +48,7 @@ use protobuf::SingularPtrField; use oci::State as OCIState; use std::collections::HashMap; use std::os::unix::io::FromRawFd; +use std::str::FromStr; use slog::{info, o, Logger}; @@ -55,6 +56,7 @@ use crate::pipestream::PipeStream; use crate::sync::{read_sync, write_count, write_sync, SYNC_DATA, SYNC_FAILED, SYNC_SUCCESS}; use crate::sync_with_async::{read_async, write_async}; use async_trait::async_trait; +use rlimit::{setrlimit, Resource, Rlim}; use tokio::io::AsyncBufReadExt; const STATE_FILENAME: &str = "state.json"; @@ -338,7 +340,6 @@ pub fn init_child() { fn do_init_child(cwfd: RawFd) -> Result<()> { lazy_static::initialize(&NAMESPACES); lazy_static::initialize(&DEFAULT_DEVICES); - lazy_static::initialize(&RLIMITMAPS); let init = std::env::var(INIT)?.eq(format!("{}", true).as_str()); @@ -461,7 +462,11 @@ fn do_init_child(cwfd: RawFd) -> Result<()> { // set rlimit for rl in p.rlimits.iter() { log_child!(cfd_log, "set resource limit: {:?}", rl); - setrlimit(rl)?; + setrlimit( + Resource::from_str(&rl.r#type)?, + Rlim::from_raw(rl.soft), + Rlim::from_raw(rl.hard), + )?; } // @@ -1436,48 +1441,6 @@ type RlimitsType = libc::c_int; #[cfg(target_env = "gnu")] type RlimitsType = libc::__rlimit_resource_t; -lazy_static! { - pub static ref RLIMITMAPS: HashMap = { - let mut m = HashMap::new(); - m.insert("RLIMIT_CPU".to_string(), libc::RLIMIT_CPU); - m.insert("RLIMIT_FSIZE".to_string(), libc::RLIMIT_FSIZE); - m.insert("RLIMIT_DATA".to_string(), libc::RLIMIT_DATA); - m.insert("RLIMIT_STACK".to_string(), libc::RLIMIT_STACK); - m.insert("RLIMIT_CORE".to_string(), libc::RLIMIT_CORE); - m.insert("RLIMIT_RSS".to_string(), libc::RLIMIT_RSS); - m.insert("RLIMIT_NPROC".to_string(), libc::RLIMIT_NPROC); - m.insert("RLIMIT_NOFILE".to_string(), libc::RLIMIT_NOFILE); - m.insert("RLIMIT_MEMLOCK".to_string(), libc::RLIMIT_MEMLOCK); - m.insert("RLIMIT_AS".to_string(), libc::RLIMIT_AS); - m.insert("RLIMIT_LOCKS".to_string(), libc::RLIMIT_LOCKS); - m.insert("RLIMIT_SIGPENDING".to_string(), libc::RLIMIT_SIGPENDING); - m.insert("RLIMIT_MSGQUEUE".to_string(), libc::RLIMIT_MSGQUEUE); - m.insert("RLIMIT_NICE".to_string(), libc::RLIMIT_NICE); - m.insert("RLIMIT_RTPRIO".to_string(), libc::RLIMIT_RTPRIO); - m.insert("RLIMIT_RTTIME".to_string(), libc::RLIMIT_RTTIME); - m - }; -} - -fn setrlimit(limit: &POSIXRlimit) -> Result<()> { - let rl = libc::rlimit { - rlim_cur: limit.soft, - rlim_max: limit.hard, - }; - - let res = if RLIMITMAPS.get(limit.r#type.as_str()).is_some() { - *RLIMITMAPS.get(limit.r#type.as_str()).unwrap() - } else { - return Err(nix::Error::Sys(Errno::EINVAL).into()); - }; - - let ret = unsafe { libc::setrlimit(res as RlimitsType, &rl as *const libc::rlimit) }; - - Errno::result(ret).map(drop)?; - - Ok(()) -} - fn setgroups(grps: &[libc::gid_t]) -> Result<()> { let ret = unsafe { libc::setgroups(grps.len(), grps.as_ptr() as *const libc::gid_t) }; Errno::result(ret).map(drop)?;