mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-09-19 21:41:07 +00:00
4539236690
This patch enables the seccomp filters for the iommu worker thread. Partially fixes: #925 Signed-off-by: Bo Chen <chen.bo@intel.com>
211 lines
7.4 KiB
Rust
211 lines
7.4 KiB
Rust
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
//
|
|
// Copyright © 2020 Intel Corporation
|
|
//
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use seccomp::{
|
|
allow_syscall, BpfProgram, Error, SeccompAction, SeccompError, SeccompFilter, SyscallRuleSet,
|
|
};
|
|
use std::convert::TryInto;
|
|
|
|
pub enum Thread {
|
|
VirtioBlk,
|
|
VirtioConsole,
|
|
VirtioIommu,
|
|
VirtioNet,
|
|
VirtioPmem,
|
|
VirtioRng,
|
|
}
|
|
|
|
// The filter containing the allowed syscall rules required by the
|
|
// virtio_blk thread to function.
|
|
fn virtio_blk_thread_rules() -> Result<Vec<SyscallRuleSet>, 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_fallocate),
|
|
allow_syscall(libc::SYS_fdatasync),
|
|
allow_syscall(libc::SYS_fsync),
|
|
#[cfg(target_arch = "x86_64")]
|
|
allow_syscall(libc::SYS_ftruncate),
|
|
#[cfg(target_arch = "aarch64")]
|
|
// The definition of libc::SYS_ftruncate is missing on AArch64.
|
|
// Use a hard-code number instead.
|
|
allow_syscall(46),
|
|
allow_syscall(libc::SYS_futex),
|
|
allow_syscall(libc::SYS_lseek),
|
|
allow_syscall(libc::SYS_madvise),
|
|
allow_syscall(libc::SYS_mmap),
|
|
allow_syscall(libc::SYS_mprotect),
|
|
allow_syscall(libc::SYS_munmap),
|
|
allow_syscall(libc::SYS_openat),
|
|
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_console_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
|
|
Ok(vec![
|
|
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_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_iommu_thread_rules() -> Result<Vec<SyscallRuleSet>, 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<Vec<SyscallRuleSet>, Error> {
|
|
Ok(vec![
|
|
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),
|
|
])
|
|
}
|
|
|
|
fn virtio_pmem_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
|
|
Ok(vec![
|
|
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_fsync),
|
|
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),
|
|
])
|
|
}
|
|
|
|
fn virtio_rng_thread_rules() -> Result<Vec<SyscallRuleSet>, Error> {
|
|
Ok(vec![
|
|
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_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 get_seccomp_filter_trap(thread_type: Thread) -> Result<SeccompFilter, Error> {
|
|
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()?,
|
|
};
|
|
|
|
Ok(SeccompFilter::new(
|
|
rules.into_iter().collect(),
|
|
SeccompAction::Trap,
|
|
)?)
|
|
}
|
|
|
|
fn get_seccomp_filter_log(thread_type: Thread) -> Result<SeccompFilter, Error> {
|
|
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()?,
|
|
};
|
|
|
|
Ok(SeccompFilter::new(
|
|
rules.into_iter().collect(),
|
|
SeccompAction::Log,
|
|
)?)
|
|
}
|
|
|
|
/// Generate a BPF program based on the seccomp_action value
|
|
pub fn get_seccomp_filter(
|
|
seccomp_action: &SeccompAction,
|
|
thread_type: Thread,
|
|
) -> Result<BpfProgram, SeccompError> {
|
|
match seccomp_action {
|
|
SeccompAction::Allow => Ok(vec![]),
|
|
SeccompAction::Log => get_seccomp_filter_log(thread_type)
|
|
.and_then(|filter| filter.try_into())
|
|
.map_err(SeccompError::SeccompFilter),
|
|
_ => get_seccomp_filter_trap(thread_type)
|
|
.and_then(|filter| filter.try_into())
|
|
.map_err(SeccompError::SeccompFilter),
|
|
}
|
|
}
|