From 453923669059920250602d5fa8af256f2c433da9 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Fri, 14 Aug 2020 14:37:01 -0700 Subject: [PATCH] virtio-devices: seccomp: Add seccomp filters for iommu thread This patch enables the seccomp filters for the iommu worker thread. Partially fixes: #925 Signed-off-by: Bo Chen --- virtio-devices/src/iommu.rs | 14 ++++++++++++-- virtio-devices/src/seccomp_filters.rs | 17 +++++++++++++++++ vmm/src/device_manager.rs | 5 +++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index a9bfd8892..738999841 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -8,9 +8,11 @@ use super::{ EpollHelperHandler, Queue, VirtioDevice, VirtioDeviceType, EPOLL_HELPER_EVENT_LAST, VIRTIO_F_VERSION_1, }; +use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::{DmaRemapping, VirtioInterrupt, VirtioInterruptType}; use anyhow::anyhow; use libc::EFD_NONBLOCK; +use seccomp::{SeccompAction, SeccompFilter}; use std::collections::BTreeMap; use std::fmt::{self, Display}; use std::io; @@ -748,6 +750,7 @@ pub struct Iommu { epoll_threads: Option>>, paused: Arc, paused_sync: Arc, + seccomp_action: SeccompAction, } #[derive(Serialize, Deserialize)] @@ -759,7 +762,7 @@ struct IommuState { } impl Iommu { - pub fn new(id: String) -> io::Result<(Self, Arc)> { + pub fn new(id: String, seccomp_action: SeccompAction) -> io::Result<(Self, Arc)> { let config = VirtioIommuConfig { page_size_mask: VIRTIO_IOMMU_PAGE_SIZE_MASK, probe_size: PROBE_PROP_SIZE, @@ -789,6 +792,7 @@ impl Iommu { epoll_threads: None, paused: Arc::new(AtomicBool::new(false)), paused_sync: Arc::new(Barrier::new(2)), + seccomp_action, }, mapping, )) @@ -963,10 +967,16 @@ impl VirtioDevice for Iommu { let paused = self.paused.clone(); let paused_sync = self.paused_sync.clone(); let mut epoll_threads = Vec::new(); + // Retrieve seccomp filter for virtio_iommu thread + let virtio_iommu_seccomp_filter = + get_seccomp_filter(&self.seccomp_action, Thread::VirtioIommu) + .map_err(ActivateError::CreateSeccompFilter)?; thread::Builder::new() .name("virtio_iommu".to_string()) .spawn(move || { - if let Err(e) = handler.run(paused, paused_sync) { + if let Err(e) = SeccompFilter::apply(virtio_iommu_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 81d837070..aac498a87 100644 --- a/virtio-devices/src/seccomp_filters.rs +++ b/virtio-devices/src/seccomp_filters.rs @@ -12,6 +12,7 @@ use std::convert::TryInto; pub enum Thread { VirtioBlk, VirtioConsole, + VirtioIommu, VirtioNet, VirtioPmem, VirtioRng, @@ -81,6 +82,20 @@ fn virtio_console_thread_rules() -> Result, Error> { ]) } +fn virtio_iommu_thread_rules() -> Result, Error> { + Ok(vec![ + allow_syscall(libc::SYS_epoll_create1), + allow_syscall(libc::SYS_epoll_ctl), + allow_syscall(libc::SYS_dup), + allow_syscall(libc::SYS_epoll_pwait), + #[cfg(target_arch = "x86_64")] + allow_syscall(libc::SYS_epoll_wait), + allow_syscall(libc::SYS_futex), + allow_syscall(libc::SYS_read), + allow_syscall(libc::SYS_write), + ]) +} + fn virtio_net_thread_rules() -> Result, Error> { Ok(vec![ allow_syscall(libc::SYS_close), @@ -150,6 +165,7 @@ fn get_seccomp_filter_trap(thread_type: Thread) -> Result let rules = match thread_type { Thread::VirtioBlk => virtio_blk_thread_rules()?, Thread::VirtioConsole => virtio_console_thread_rules()?, + Thread::VirtioIommu => virtio_iommu_thread_rules()?, Thread::VirtioNet => virtio_net_thread_rules()?, Thread::VirtioPmem => virtio_pmem_thread_rules()?, Thread::VirtioRng => virtio_rng_thread_rules()?, @@ -165,6 +181,7 @@ fn get_seccomp_filter_log(thread_type: Thread) -> Result { let rules = match thread_type { Thread::VirtioBlk => virtio_blk_thread_rules()?, Thread::VirtioConsole => virtio_console_thread_rules()?, + Thread::VirtioIommu => virtio_iommu_thread_rules()?, Thread::VirtioNet => virtio_net_thread_rules()?, Thread::VirtioPmem => virtio_pmem_thread_rules()?, Thread::VirtioRng => virtio_rng_thread_rules()?, diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 54c3543d1..8d7ee18d4 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1009,8 +1009,9 @@ impl DeviceManager { let iommu_id = String::from(IOMMU_DEVICE_NAME); let (iommu_device, iommu_mapping) = if self.config.lock().unwrap().iommu { - let (device, mapping) = virtio_devices::Iommu::new(iommu_id.clone()) - .map_err(DeviceManagerError::CreateVirtioIommu)?; + let (device, mapping) = + virtio_devices::Iommu::new(iommu_id.clone(), self.seccomp_action.clone()) + .map_err(DeviceManagerError::CreateVirtioIommu)?; let device = Arc::new(Mutex::new(device)); self.iommu_device = Some(Arc::clone(&device));