From c82ded8afa907a197d5ec516bfe3bae6d64a7fb6 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Mon, 17 Aug 2020 19:58:13 -0700 Subject: [PATCH] virtio-devices: seccomp: Add seccomp filters for balloon thread This patch enables the seccomp filters for the balloon worker thread. Partially fixes: #925 Signed-off-by: Bo Chen --- virtio-devices/src/balloon.rs | 13 +++++++++++-- virtio-devices/src/seccomp_filters.rs | 24 ++++++++++++++++++++++++ vmm/src/device_manager.rs | 1 + 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index d61b5edb3..2fcde4c84 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -16,9 +16,11 @@ use super::{ ActivateError, ActivateResult, EpollHelper, EpollHelperError, EpollHelperHandler, Queue, VirtioDevice, VirtioDeviceType, EPOLL_HELPER_EVENT_LAST, VIRTIO_F_VERSION_1, }; +use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::vm_memory::GuestMemory; use crate::{VirtioInterrupt, VirtioInterruptType}; use libc::EFD_NONBLOCK; +use seccomp::{SeccompAction, SeccompFilter}; use std::io; use std::mem::size_of; use std::os::unix::io::AsRawFd; @@ -318,11 +320,12 @@ pub struct Balloon { epoll_threads: Option>>, paused: Arc, paused_sync: Arc, + seccomp_action: SeccompAction, } impl Balloon { // Create a new virtio-balloon. - pub fn new(id: String, size: u64) -> io::Result { + pub fn new(id: String, size: u64, seccomp_action: SeccompAction) -> io::Result { let avail_features = 1u64 << VIRTIO_F_VERSION_1; let mut config = VirtioBalloonConfig::default(); @@ -341,6 +344,7 @@ impl Balloon { epoll_threads: None, paused: Arc::new(AtomicBool::new(false)), paused_sync: Arc::new(Barrier::new(2)), + seccomp_action, }) } @@ -451,10 +455,15 @@ impl VirtioDevice for Balloon { let paused = self.paused.clone(); let paused_sync = self.paused_sync.clone(); let mut epoll_threads = Vec::new(); + let virtio_balloon_seccomp_filter = + get_seccomp_filter(&self.seccomp_action, Thread::VirtioBalloon) + .map_err(ActivateError::CreateSeccompFilter)?; thread::Builder::new() .name("virtio_balloon".to_string()) .spawn(move || { - if let Err(e) = handler.run(paused, paused_sync) { + if let Err(e) = SeccompFilter::apply(virtio_balloon_seccomp_filter) { + error!("Error applying seccomp filter: {:?}", e); + } else if let Err(e) = handler.run(paused, paused_sync) { error!("Error running worker: {:?}", e); } }) diff --git a/virtio-devices/src/seccomp_filters.rs b/virtio-devices/src/seccomp_filters.rs index 94b40530e..ea1e2cd16 100644 --- a/virtio-devices/src/seccomp_filters.rs +++ b/virtio-devices/src/seccomp_filters.rs @@ -10,6 +10,7 @@ use seccomp::{ use std::convert::TryInto; pub enum Thread { + VirtioBalloon, VirtioBlk, VirtioConsole, VirtioIommu, @@ -20,6 +21,27 @@ pub enum Thread { VirtioRng, } +fn virtio_balloon_thread_rules() -> Result, Error> { + Ok(vec![ + allow_syscall(libc::SYS_brk), + allow_syscall(libc::SYS_close), + allow_syscall(libc::SYS_dup), + allow_syscall(libc::SYS_epoll_create1), + allow_syscall(libc::SYS_epoll_ctl), + allow_syscall(libc::SYS_epoll_pwait), + #[cfg(target_arch = "x86_64")] + allow_syscall(libc::SYS_epoll_wait), + allow_syscall(libc::SYS_exit), + allow_syscall(libc::SYS_futex), + allow_syscall(libc::SYS_madvise), + allow_syscall(libc::SYS_munmap), + allow_syscall(libc::SYS_read), + allow_syscall(libc::SYS_rt_sigprocmask), + allow_syscall(libc::SYS_sigaltstack), + allow_syscall(libc::SYS_write), + ]) +} + // The filter containing the allowed syscall rules required by the // virtio_blk thread to function. fn virtio_blk_thread_rules() -> Result, Error> { @@ -208,6 +230,7 @@ fn virtio_rng_thread_rules() -> Result, Error> { fn get_seccomp_filter_trap(thread_type: Thread) -> Result { let rules = match thread_type { + Thread::VirtioBalloon => virtio_balloon_thread_rules()?, Thread::VirtioBlk => virtio_blk_thread_rules()?, Thread::VirtioConsole => virtio_console_thread_rules()?, Thread::VirtioIommu => virtio_iommu_thread_rules()?, @@ -226,6 +249,7 @@ fn get_seccomp_filter_trap(thread_type: Thread) -> Result fn get_seccomp_filter_log(thread_type: Thread) -> Result { let rules = match thread_type { + Thread::VirtioBalloon => virtio_balloon_thread_rules()?, Thread::VirtioBlk => virtio_blk_thread_rules()?, Thread::VirtioConsole => virtio_console_thread_rules()?, Thread::VirtioIommu => virtio_iommu_thread_rules()?, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index ca0d1c084..ec7c65710 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -2452,6 +2452,7 @@ impl DeviceManager { virtio_devices::Balloon::new( id.clone(), self.config.lock().unwrap().memory.balloon_size, + self.seccomp_action.clone(), ) .map_err(DeviceManagerError::CreateVirtioBalloon)?, ));