diff --git a/virtio-devices/src/console.rs b/virtio-devices/src/console.rs index 6dc54e579..cd6f2de75 100644 --- a/virtio-devices/src/console.rs +++ b/virtio-devices/src/console.rs @@ -6,9 +6,11 @@ use super::{ ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType, VirtioInterruptType, VIRTIO_F_IOMMU_PLATFORM, VIRTIO_F_VERSION_1, }; +use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::VirtioInterrupt; use anyhow::anyhow; use libc::EFD_NONBLOCK; +use seccomp::{SeccompAction, SeccompFilter}; use serde::ser::{Serialize, SerializeStruct, Serializer}; use std::cmp; use std::collections::VecDeque; @@ -396,6 +398,7 @@ pub struct Console { interrupt_cb: Option>, epoll_threads: Option>>>, paused: Arc, + seccomp_action: SeccompAction, } #[derive(Serialize, Deserialize)] @@ -414,6 +417,7 @@ impl Console { cols: u16, rows: u16, iommu: bool, + seccomp_action: SeccompAction, ) -> io::Result<(Console, Arc)> { let mut avail_features = 1u64 << VIRTIO_F_VERSION_1 | 1u64 << VIRTIO_CONSOLE_F_SIZE; @@ -446,6 +450,7 @@ impl Console { interrupt_cb: None, epoll_threads: None, paused: Arc::new(AtomicBool::new(false)), + seccomp_action, }, console_input, )) @@ -583,9 +588,18 @@ impl VirtioDevice for Console { let paused = self.paused.clone(); let mut epoll_threads = Vec::new(); + // Retrieve seccomp filter for virtio_console thread + let virtio_console_seccomp_filter = + get_seccomp_filter(&self.seccomp_action, Thread::VirtioConsole) + .map_err(ActivateError::CreateSeccompFilter)?; thread::Builder::new() .name("virtio_console".to_string()) - .spawn(move || handler.run(paused)) + .spawn(move || { + SeccompFilter::apply(virtio_console_seccomp_filter) + .map_err(DeviceError::ApplySeccompFilter)?; + + handler.run(paused) + }) .map(|thread| epoll_threads.push(thread)) .map_err(|e| { error!("failed to clone the virtio-console epoll thread: {}", e); diff --git a/virtio-devices/src/seccomp_filters.rs b/virtio-devices/src/seccomp_filters.rs index 7124b01b5..8ab3f9b95 100644 --- a/virtio-devices/src/seccomp_filters.rs +++ b/virtio-devices/src/seccomp_filters.rs @@ -11,6 +11,7 @@ use std::convert::TryInto; pub enum Thread { VirtioBlk, + VirtioConsole, VirtioRng, } @@ -53,6 +54,30 @@ fn virtio_blk_thread_rules() -> Result, Error> { ]) } +fn virtio_console_thread_rules() -> Result, Error> { + Ok(vec![ + allow_syscall(libc::SYS_close), + 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_mmap), + allow_syscall(libc::SYS_mprotect), + allow_syscall(libc::SYS_munmap), + allow_syscall(libc::SYS_prctl), + allow_syscall(libc::SYS_read), + allow_syscall(libc::SYS_rt_sigprocmask), + allow_syscall(libc::SYS_sched_getaffinity), + allow_syscall(libc::SYS_set_robust_list), + allow_syscall(libc::SYS_sigaltstack), + allow_syscall(libc::SYS_write), + ]) +} + fn virtio_rng_thread_rules() -> Result, Error> { Ok(vec![ allow_syscall(libc::SYS_close), @@ -80,6 +105,7 @@ fn virtio_rng_thread_rules() -> Result, Error> { 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::VirtioRng => virtio_rng_thread_rules()?, }; @@ -92,6 +118,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::VirtioBlk => virtio_blk_thread_rules()?, + Thread::VirtioConsole => virtio_console_thread_rules()?, Thread::VirtioRng => virtio_rng_thread_rules()?, }; diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 9a36d3ff8..75b884756 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1515,9 +1515,15 @@ impl DeviceManager { let virtio_console_input = if let Some(writer) = console_writer { let id = String::from(CONSOLE_DEVICE_NAME); - let (virtio_console_device, virtio_console_input) = - virtio_devices::Console::new(id.clone(), writer, col, row, console_config.iommu) - .map_err(DeviceManagerError::CreateVirtioConsole)?; + let (virtio_console_device, virtio_console_input) = virtio_devices::Console::new( + id.clone(), + writer, + col, + row, + console_config.iommu, + self.seccomp_action.clone(), + ) + .map_err(DeviceManagerError::CreateVirtioConsole)?; let virtio_console_device = Arc::new(Mutex::new(virtio_console_device)); virtio_devices.push(( Arc::clone(&virtio_console_device) as VirtioDeviceArc,