From 896b9a1d4b0d395c7c6bfdf87423ff3f0e2fc789 Mon Sep 17 00:00:00 2001 From: Bo Chen Date: Mon, 17 Aug 2020 21:44:51 -0700 Subject: [PATCH] virtio-devices: seccomp: Add seccomp filter for vhost_net_ctl thread This patch enables the seccomp filters for the vhost_net_ctl worker thread. Partially fixes: #925 Signed-off-by: Bo Chen --- virtio-devices/src/seccomp_filters.rs | 17 +++++++++++++++++ virtio-devices/src/vhost_user/net.rs | 20 +++++++++++++++++--- vmm/src/device_manager.rs | 9 +++++++-- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/virtio-devices/src/seccomp_filters.rs b/virtio-devices/src/seccomp_filters.rs index cd094db53..baa14a031 100644 --- a/virtio-devices/src/seccomp_filters.rs +++ b/virtio-devices/src/seccomp_filters.rs @@ -20,6 +20,7 @@ pub enum Thread { VirtioPmem, VirtioRng, VirtioVhostFs, + VirtioVhostNetCtl, } fn virtio_balloon_thread_rules() -> Result, Error> { @@ -253,6 +254,20 @@ fn virtio_vhost_fs_thread_rules() -> Result, Error> { ]) } +fn virtio_vhost_net_ctl_thread_rules() -> Result, Error> { + Ok(vec![ + allow_syscall(libc::SYS_brk), + 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_futex), + allow_syscall(libc::SYS_read), + ]) +} + fn get_seccomp_filter_trap(thread_type: Thread) -> Result { let rules = match thread_type { Thread::VirtioBalloon => virtio_balloon_thread_rules()?, @@ -265,6 +280,7 @@ fn get_seccomp_filter_trap(thread_type: Thread) -> Result Thread::VirtioPmem => virtio_pmem_thread_rules()?, Thread::VirtioRng => virtio_rng_thread_rules()?, Thread::VirtioVhostFs => virtio_vhost_fs_thread_rules()?, + Thread::VirtioVhostNetCtl => virtio_vhost_net_ctl_thread_rules()?, }; Ok(SeccompFilter::new( @@ -285,6 +301,7 @@ fn get_seccomp_filter_log(thread_type: Thread) -> Result { Thread::VirtioPmem => virtio_pmem_thread_rules()?, Thread::VirtioRng => virtio_rng_thread_rules()?, Thread::VirtioVhostFs => virtio_vhost_fs_thread_rules()?, + Thread::VirtioVhostNetCtl => virtio_vhost_net_ctl_thread_rules()?, }; Ok(SeccompFilter::new( diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index 13b617f0b..1f5570cf1 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -8,9 +8,11 @@ use super::super::{ActivateError, ActivateResult, Queue, VirtioDevice, VirtioDev use super::handler::*; use super::vu_common_ctrl::*; use super::{Error, Result}; +use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::VirtioInterrupt; use libc::EFD_NONBLOCK; use net_util::MacAddr; +use seccomp::{SeccompAction, SeccompFilter}; use std::os::unix::io::AsRawFd; use std::result; use std::sync::atomic::{AtomicBool, Ordering}; @@ -47,12 +49,18 @@ pub struct Net { ctrl_queue_epoll_thread: Option>, paused: Arc, paused_sync: Arc, + seccomp_action: SeccompAction, } impl Net { /// Create a new vhost-user-net device /// Create a new vhost-user-net device - pub fn new(id: String, mac_addr: MacAddr, vu_cfg: VhostUserConfig) -> Result { + pub fn new( + id: String, + mac_addr: MacAddr, + vu_cfg: VhostUserConfig, + seccomp_action: SeccompAction, + ) -> Result { let mut vhost_user_net = Master::connect(&vu_cfg.socket, vu_cfg.num_queues as u64) .map_err(Error::VhostUserCreateMaster)?; @@ -153,6 +161,7 @@ impl Net { ctrl_queue_epoll_thread: None, paused: Arc::new(AtomicBool::new(false)), paused_sync: Arc::new(Barrier::new((vu_cfg.num_queues / 2) + 1)), + seccomp_action, }) } } @@ -264,10 +273,15 @@ impl VirtioDevice for Net { // the pause. self.paused_sync = Arc::new(Barrier::new((queue_num / 2) + 2)); let paused_sync = self.paused_sync.clone(); + let virtio_vhost_net_ctl_seccomp_filter = + get_seccomp_filter(&self.seccomp_action, Thread::VirtioVhostNetCtl) + .map_err(ActivateError::CreateSeccompFilter)?; thread::Builder::new() - .name("virtio_net".to_string()) + .name("vhost_net_ctl".to_string()) .spawn(move || { - if let Err(e) = ctrl_handler.run_ctrl(paused, paused_sync) { + if let Err(e) = SeccompFilter::apply(virtio_vhost_net_ctl_seccomp_filter) { + error!("Error applying seccomp filter: {:?}", e); + } else if let Err(e) = ctrl_handler.run_ctrl(paused, paused_sync) { error!("Error running worker: {:?}", e); } }) diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 068e151db..2e9c06274 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1874,8 +1874,13 @@ impl DeviceManager { queue_size: net_cfg.queue_size, }; let vhost_user_net_device = Arc::new(Mutex::new( - virtio_devices::vhost_user::Net::new(id.clone(), net_cfg.mac, vu_cfg) - .map_err(DeviceManagerError::CreateVhostUserNet)?, + virtio_devices::vhost_user::Net::new( + id.clone(), + net_cfg.mac, + vu_cfg, + self.seccomp_action.clone(), + ) + .map_err(DeviceManagerError::CreateVhostUserNet)?, )); // Fill the device tree with a new node. In case of restore, we