diff --git a/Cargo.lock b/Cargo.lock index 649b2eb4e..4afa7ae0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,6 +165,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "seccomp 0.1.0 (git+https://github.com/firecracker-microvm/firecracker?tag=v0.21.1)", "serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", "ssh2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 2ef331b0a..3e3cac79b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ futures = { version = "0.3.4", features = ["thread-pool"] } lazy_static = "1.4.0" libc = "0.2.68" log = { version = "0.4.8", features = ["std"] } +seccomp = { git = "https://github.com/firecracker-microvm/firecracker", tag = "v0.21.1" } serde_json = ">=1.0.9" vhost_user_backend = { path = "vhost_user_backend"} vhost_user_block = { path = "vhost_user_block"} diff --git a/src/main.rs b/src/main.rs index 8cfa22811..4c8c04ac7 100755 --- a/src/main.rs +++ b/src/main.rs @@ -12,6 +12,7 @@ extern crate clap; use clap::{App, Arg, ArgGroup, ArgMatches}; use libc::EFD_NONBLOCK; use log::LevelFilter; +use seccomp::SeccompLevel; use std::sync::mpsc::channel; use std::sync::{Arc, Mutex}; use std::{env, process}; @@ -298,6 +299,7 @@ fn start_vmm(cmd_arguments: ArgMatches) { api_evt.try_clone().unwrap(), http_sender, api_request_receiver, + &SeccompLevel::None, ) { Ok(t) => t, Err(e) => { diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index c462979f0..58f2e2fa6 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -17,8 +17,10 @@ extern crate vmm_sys_util; use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo, VmmPingResponse}; use crate::config::{DeviceConfig, VmConfig}; +use crate::seccomp_filters::get_seccomp_filter; use crate::vm::{Error as VmError, Vm, VmState}; use libc::EFD_NONBLOCK; +use seccomp::{SeccompFilter, SeccompLevel}; use std::io; use std::os::unix::io::{AsRawFd, RawFd}; use std::path::PathBuf; @@ -34,6 +36,7 @@ pub mod cpu; pub mod device_manager; pub mod interrupt; pub mod memory_manager; +pub mod seccomp_filters; pub mod vm; #[cfg(feature = "acpi")] @@ -84,6 +87,12 @@ pub enum Error { // Error following "exe" link ExePathReadLink(io::Error), + + /// Cannot create seccomp filter + CreateSeccompFilter(seccomp::SeccompError), + + /// Cannot apply seccomp filter + ApplySeccompFilter(seccomp::Error), } pub type Result = result::Result; @@ -161,9 +170,14 @@ pub fn start_vmm_thread( api_event: EventFd, api_sender: Sender, api_receiver: Receiver, + seccomp_level: &SeccompLevel, ) -> Result>> { let http_api_event = api_event.try_clone().map_err(Error::EventFdClone)?; + // Retrieve seccomp filter + let vmm_seccomp_filter = + get_seccomp_filter(seccomp_level).map_err(Error::CreateSeccompFilter)?; + // Find the path that the "/proc//exe" symlink points to. Must be done before spawning // a thread as Rust does not put the child threads in the same thread group which prevents the // link from being followed as per PTRACE_MODE_READ_FSCREDS (see proc(5) and ptrace(2)). The @@ -173,6 +187,9 @@ pub fn start_vmm_thread( let thread = thread::Builder::new() .name("vmm".to_string()) .spawn(move || { + // Apply seccomp filter for VMM thread. + SeccompFilter::apply(vmm_seccomp_filter).map_err(Error::ApplySeccompFilter)?; + let mut vmm = Vmm::new(vmm_version.to_string(), api_event, vmm_path)?; vmm.control_loop(Arc::new(api_receiver))