vmm: seccomp: Add seccomp filters for signal_handler worker thread

This patch covers the last worker thread with dedicated secomp filters.

Fixes: #925

Signed-off-by: Bo Chen <chen.bo@intel.com>
This commit is contained in:
Bo Chen 2020-09-09 16:33:58 -07:00 committed by Sebastien Boeuf
parent 2612a6df29
commit 9682d74763
2 changed files with 68 additions and 3 deletions

View File

@ -13,6 +13,7 @@ use std::convert::TryInto;
pub enum Thread {
Api,
SignalHandler,
Vcpu,
Vmm,
}
@ -238,6 +239,28 @@ fn create_api_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, Error> {
Ok(or![and![Cond::new(1, ArgLen::DWORD, Eq, FIONBIO)?],])
}
fn create_signal_handler_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, Error> {
Ok(or![and![Cond::new(1, ArgLen::DWORD, Eq, TIOCGWINSZ)?],])
}
fn signal_handler_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
Ok(vec![
allow_syscall(libc::SYS_brk),
allow_syscall(libc::SYS_close),
allow_syscall(libc::SYS_exit),
allow_syscall(libc::SYS_exit_group),
allow_syscall(libc::SYS_futex),
allow_syscall_if(libc::SYS_ioctl, create_signal_handler_ioctl_seccomp_rule()?),
allow_syscall(libc::SYS_madvise),
allow_syscall(libc::SYS_munmap),
allow_syscall(libc::SYS_recvfrom),
allow_syscall(libc::SYS_rt_sigprocmask),
allow_syscall(libc::SYS_sendto),
allow_syscall(libc::SYS_sigaltstack),
allow_syscall(libc::SYS_write),
])
}
// The filter containing the white listed syscall rules required by the VMM to
// function.
fn vmm_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
@ -460,6 +483,7 @@ fn api_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
fn get_seccomp_filter_trap(thread_type: Thread) -> Result<SeccompFilter, Error> {
let rules = match thread_type {
Thread::Api => api_thread_rules()?,
Thread::SignalHandler => signal_handler_thread_rules()?,
Thread::Vcpu => vcpu_thread_rules()?,
Thread::Vmm => vmm_thread_rules()?,
};
@ -473,6 +497,7 @@ fn get_seccomp_filter_trap(thread_type: Thread) -> Result<SeccompFilter, Error>
fn get_seccomp_filter_log(thread_type: Thread) -> Result<SeccompFilter, Error> {
let rules = match thread_type {
Thread::Api => api_thread_rules()?,
Thread::SignalHandler => signal_handler_thread_rules()?,
Thread::Vcpu => vcpu_thread_rules()?,
Thread::Vmm => vmm_thread_rules()?,
};

View File

@ -33,6 +33,7 @@ use crate::cpu;
use crate::device_manager::{self, get_win_size, Console, DeviceManager, DeviceManagerError};
use crate::memory_manager::{Error as MemoryManagerError, MemoryManager};
use crate::migration::{get_vm_snapshot, url_to_path, VM_SNAPSHOT_FILE};
use crate::seccomp_filters::{get_seccomp_filter, Thread};
use crate::{
PciDeviceInfo, CPU_MANAGER_SNAPSHOT_ID, DEVICE_MANAGER_SNAPSHOT_ID, MEMORY_MANAGER_SNAPSHOT_ID,
};
@ -47,7 +48,7 @@ use linux_loader::loader::elf::Error::InvalidElfMagicNumber;
#[cfg(target_arch = "x86_64")]
use linux_loader::loader::elf::PvhBootCapability::PvhEntryPresent;
use linux_loader::loader::KernelLoader;
use seccomp::SeccompAction;
use seccomp::{SeccompAction, SeccompFilter};
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
use std::collections::{BTreeMap, HashMap};
use std::convert::TryInto;
@ -202,6 +203,12 @@ pub enum Error {
/// Invalid configuration for NUMA.
InvalidNumaConfig,
/// Cannot create seccomp filter
CreateSeccompFilter(seccomp::SeccompError),
/// Cannot apply seccomp filter
ApplySeccompFilter(seccomp::Error),
}
pub type Result<T> = result::Result<T, Error>;
@ -288,6 +295,7 @@ pub struct Vm {
saved_clock: Option<hypervisor::ClockData>,
#[cfg(feature = "acpi")]
numa_nodes: NumaNodes,
seccomp_action: SeccompAction,
}
impl Vm {
@ -365,6 +373,7 @@ impl Vm {
saved_clock: _saved_clock,
#[cfg(feature = "acpi")]
numa_nodes,
seccomp_action: seccomp_action.clone(),
})
}
@ -1237,10 +1246,22 @@ impl Vm {
self.signals = Some(signals.clone());
let on_tty = self.on_tty;
let signal_handler_seccomp_filter =
get_seccomp_filter(&self.seccomp_action, Thread::SignalHandler)
.map_err(Error::CreateSeccompFilter)?;
self.threads.push(
thread::Builder::new()
.name("signal_handler".to_string())
.spawn(move || Vm::os_signal_handler(signals, console, on_tty))
.spawn(move || {
if let Err(e) = SeccompFilter::apply(signal_handler_seccomp_filter)
.map_err(Error::ApplySeccompFilter)
{
error!("Error applying seccomp filter: {:?}", e);
return;
}
Vm::os_signal_handler(signals, console, on_tty);
})
.map_err(Error::SignalHandlerSpawn)?,
);
}
@ -1461,10 +1482,29 @@ impl Snapshottable for Vm {
self.signals = Some(signals.clone());
let on_tty = self.on_tty;
let signal_handler_seccomp_filter =
get_seccomp_filter(&self.seccomp_action, Thread::SignalHandler).map_err(
|e| {
MigratableError::Restore(anyhow!(
"Could not create seccomp filter: {:#?}",
Error::CreateSeccompFilter(e)
))
},
)?;
self.threads.push(
thread::Builder::new()
.name("signal_handler".to_string())
.spawn(move || Vm::os_signal_handler(signals, console, on_tty))
.spawn(move || {
if let Err(e) = SeccompFilter::apply(signal_handler_seccomp_filter)
.map_err(Error::ApplySeccompFilter)
{
error!("Error applying seccomp filter: {:?}", e);
return;
}
Vm::os_signal_handler(signals, console, on_tty)
})
.map_err(|e| {
MigratableError::Restore(anyhow!(
"Could not start console signal thread: {:#?}",