mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: migration seccomp: add for TCP workers (send and receive)
On-behalf-of: SAP philipp.schuster@sap.com Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
This commit is contained in:
committed by
Bo Chen
parent
fd88e23ecb
commit
1ae1cc787d
@@ -980,7 +980,12 @@ impl Vmm {
|
||||
// The accept thread hands the page fault connection back via this channel.
|
||||
let (fault_tx, fault_rx) = channel();
|
||||
let connections = listener.try_clone().and_then(|l| {
|
||||
ReceiveAdditionalConnections::new(l, guest_memory.clone(), fault_tx)
|
||||
ReceiveAdditionalConnections::new(
|
||||
l,
|
||||
guest_memory.clone(),
|
||||
fault_tx,
|
||||
&self.seccomp_action,
|
||||
)
|
||||
})?;
|
||||
Ok(ReceiveMigrationConfiguredData {
|
||||
memory_manager,
|
||||
@@ -1652,6 +1657,7 @@ impl Vmm {
|
||||
send_data_migration.connections,
|
||||
send_data_migration.tls_dir.as_deref(),
|
||||
&vm.guest_memory(),
|
||||
&seccomp_filters.tcp_worker,
|
||||
)?;
|
||||
|
||||
Self::do_memory_migration(
|
||||
@@ -3159,6 +3165,16 @@ impl RequestHandler for Vmm {
|
||||
))
|
||||
})?;
|
||||
|
||||
let tcp_worker =
|
||||
get_seccomp_filter(&self.seccomp_action, Thread::MigrationTcpWorker, None)
|
||||
.map_err(|e| {
|
||||
MigratableError::MigrateSend(anyhow!(
|
||||
"Error creating migration TCP worker seccomp filter: {e}"
|
||||
))
|
||||
})?;
|
||||
|
||||
// Build the seccomp filter on the parent thread so any failure aborts
|
||||
// the migration before the serve thread is spawned.
|
||||
let postcopy_server =
|
||||
get_seccomp_filter(&self.seccomp_action, Thread::MigrateSendPostcopy, None)
|
||||
.map_err(|e| {
|
||||
@@ -3169,6 +3185,7 @@ impl RequestHandler for Vmm {
|
||||
|
||||
MigrationSeccompFilters {
|
||||
worker,
|
||||
tcp_worker,
|
||||
postcopy_server,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ use std::{mem, thread};
|
||||
|
||||
use anyhow::{Context, anyhow};
|
||||
use log::{debug, error, info, warn};
|
||||
use seccompiler::{BpfProgram, SeccompAction, apply_filter};
|
||||
use serde_json;
|
||||
use thiserror::Error;
|
||||
use vm_memory::bitmap::BitmapSlice;
|
||||
@@ -30,6 +31,7 @@ use vm_migration::tls::{TlsServerConfig, TlsStream};
|
||||
use vm_migration::{MigratableError, Snapshot};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
use crate::seccomp_filters::{Thread, get_seccomp_filter};
|
||||
use crate::sync_utils::Gate;
|
||||
use crate::{GuestMemoryMmap, VmMigrationConfig};
|
||||
|
||||
@@ -308,6 +310,7 @@ impl ReceiveAdditionalConnections {
|
||||
listener: ReceiveListener,
|
||||
guest_memory: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
fault_tx: Sender<SocketStream>,
|
||||
seccomp_action: &SeccompAction,
|
||||
) -> Result<Self, MigratableError> {
|
||||
let event_fd = EventFd::new(0)
|
||||
.context("Error creating terminate fd")
|
||||
@@ -318,10 +321,26 @@ impl ReceiveAdditionalConnections {
|
||||
.context("Error cloning terminate fd")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
|
||||
let seccomp_filter = get_seccomp_filter(seccomp_action, Thread::MigrationTcpWorker, None)
|
||||
.context("Error creating migration TCP worker seccomp filter")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
|
||||
let accept_thread = thread::Builder::new()
|
||||
.name("migrate-receive-accept-connections".to_owned())
|
||||
.spawn(move || {
|
||||
Self::accept_connections(listener, &terminate_fd, &guest_memory, &fault_tx)
|
||||
if !seccomp_filter.is_empty() {
|
||||
apply_filter(&seccomp_filter)
|
||||
.context("Error applying migration TCP worker seccomp filter")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
}
|
||||
|
||||
Self::accept_connections(
|
||||
listener,
|
||||
&terminate_fd,
|
||||
&guest_memory,
|
||||
&fault_tx,
|
||||
&seccomp_filter,
|
||||
)
|
||||
})
|
||||
.context("Error creating connection accept thread")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
@@ -348,6 +367,7 @@ impl ReceiveAdditionalConnections {
|
||||
terminate_fd: &EventFd,
|
||||
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
fault_tx: &Sender<SocketStream>,
|
||||
seccomp_filter: &BpfProgram,
|
||||
) -> Result<(), MigratableError> {
|
||||
let mut threads = Vec::new();
|
||||
let first_err = Self::accept_connections_loop(
|
||||
@@ -356,6 +376,7 @@ impl ReceiveAdditionalConnections {
|
||||
guest_memory,
|
||||
fault_tx,
|
||||
&mut threads,
|
||||
seccomp_filter,
|
||||
);
|
||||
|
||||
if first_err.is_err() {
|
||||
@@ -380,6 +401,7 @@ impl ReceiveAdditionalConnections {
|
||||
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
fault_tx: &Sender<SocketStream>,
|
||||
threads: &mut Vec<thread::JoinHandle<Result<(), MigratableError>>>,
|
||||
seccomp_filter: &BpfProgram,
|
||||
) -> Result<(), MigratableError> {
|
||||
loop {
|
||||
let socket = listener.abortable_accept(terminate_fd)?;
|
||||
@@ -402,6 +424,7 @@ impl ReceiveAdditionalConnections {
|
||||
threads.len(),
|
||||
terminate_fd,
|
||||
guest_memory.clone(),
|
||||
seccomp_filter,
|
||||
)?;
|
||||
threads.push(thread);
|
||||
}
|
||||
@@ -456,15 +479,24 @@ impl ReceiveAdditionalConnections {
|
||||
index: usize,
|
||||
terminate_fd: &EventFd,
|
||||
guest_memory: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
seccomp_filter: &BpfProgram,
|
||||
) -> Result<thread::JoinHandle<Result<(), MigratableError>>, MigratableError> {
|
||||
let terminate_fd = terminate_fd
|
||||
.try_clone()
|
||||
.context("Error cloning terminate fd")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
|
||||
let seccomp_filter_t = seccomp_filter.clone();
|
||||
thread::Builder::new()
|
||||
.name(format!("migrate-receive-memory-{index}"))
|
||||
.spawn(move || Self::worker_receive_memory(&mut socket, &terminate_fd, &guest_memory))
|
||||
.spawn(move || {
|
||||
if !seccomp_filter_t.is_empty() {
|
||||
apply_filter(&seccomp_filter_t)
|
||||
.context("Error applying migration TCP worker seccomp filter")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
}
|
||||
Self::worker_receive_memory(&mut socket, &terminate_fd, &guest_memory)
|
||||
})
|
||||
.map_err(|e| {
|
||||
error!("Error spawning receive-memory thread: {e}");
|
||||
MigratableError::MigrateReceive(
|
||||
@@ -652,6 +684,7 @@ impl SendAdditionalConnections {
|
||||
connections: NonZeroU32,
|
||||
tls_dir: Option<&Path>,
|
||||
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
seccomp_filter: &BpfProgram,
|
||||
) -> Result<Self, MigratableError> {
|
||||
let mut threads = Vec::new();
|
||||
let configured_connections = connections.get();
|
||||
@@ -683,10 +716,17 @@ impl SendAdditionalConnections {
|
||||
let message_rx = message_rx.clone();
|
||||
let worker_error = worker_error.clone();
|
||||
let notify_tx = notify_tx.clone();
|
||||
let seccomp_filter = seccomp_filter.clone();
|
||||
|
||||
let thread = thread::Builder::new()
|
||||
.name(format!("migrate-send-memory-{n}"))
|
||||
.spawn(move || {
|
||||
if !seccomp_filter.is_empty() {
|
||||
apply_filter(&seccomp_filter)
|
||||
.context("Error applying migration TCP worker seccomp filter")
|
||||
.map_err(MigratableError::MigrateReceive)?;
|
||||
}
|
||||
|
||||
Self::worker_send_memory(
|
||||
&mut socket,
|
||||
&guest_memory,
|
||||
|
||||
@@ -72,6 +72,7 @@ impl Drop for MigrationWorkerHandle {
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MigrationSeccompFilters {
|
||||
pub worker: BpfProgram,
|
||||
pub tcp_worker: BpfProgram,
|
||||
pub postcopy_server: BpfProgram,
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,11 @@ pub enum Thread {
|
||||
#[cfg(feature = "dbus_api")]
|
||||
DBusApi,
|
||||
EventMonitor,
|
||||
/// Thread handling the migration on the sending side.
|
||||
MigrationWorker,
|
||||
/// Key used for the TCP workers for send and receive, as well as the accept
|
||||
/// thread on the receiver side.
|
||||
MigrationTcpWorker,
|
||||
SignalHandler,
|
||||
Vcpu,
|
||||
Vmm,
|
||||
@@ -1124,6 +1128,52 @@ fn migration_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError
|
||||
])
|
||||
}
|
||||
|
||||
fn migration_tcp_worker_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
|
||||
Ok(vec![
|
||||
(libc::SYS_accept4, vec![]),
|
||||
(libc::SYS_brk, vec![]),
|
||||
(libc::SYS_clock_gettime, vec![]),
|
||||
(libc::SYS_clone, vec![]),
|
||||
(libc::SYS_clone3, vec![]),
|
||||
(libc::SYS_close, vec![]),
|
||||
(libc::SYS_exit, vec![]),
|
||||
(libc::SYS_exit_group, vec![]),
|
||||
(libc::SYS_fcntl, vec![]),
|
||||
(libc::SYS_futex, vec![]),
|
||||
(libc::SYS_getrandom, vec![]),
|
||||
(libc::SYS_gettid, vec![]),
|
||||
(libc::SYS_madvise, vec![]),
|
||||
(libc::SYS_mmap, vec![]),
|
||||
(libc::SYS_mprotect, vec![]),
|
||||
(libc::SYS_munmap, vec![]),
|
||||
(libc::SYS_openat, vec![]),
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
(libc::SYS_poll, vec![]),
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
|
||||
(libc::SYS_ppoll, vec![]),
|
||||
(libc::SYS_prctl, vec![]),
|
||||
(libc::SYS_pwrite64, vec![]),
|
||||
(libc::SYS_read, vec![]),
|
||||
(libc::SYS_readv, vec![]),
|
||||
(libc::SYS_recvfrom, vec![]),
|
||||
(libc::SYS_recvmsg, vec![]),
|
||||
(libc::SYS_rseq, vec![]),
|
||||
(libc::SYS_rt_sigprocmask, vec![]),
|
||||
(libc::SYS_rt_sigreturn, vec![]),
|
||||
(libc::SYS_sched_getaffinity, vec![]),
|
||||
(libc::SYS_sched_yield, vec![]),
|
||||
// We are already inheriting seccomp from the parent thread.
|
||||
(libc::SYS_seccomp, vec![]),
|
||||
(libc::SYS_sendmsg, vec![]),
|
||||
(libc::SYS_sendto, vec![]),
|
||||
(libc::SYS_set_robust_list, vec![]),
|
||||
(libc::SYS_setsockopt, vec![]),
|
||||
(libc::SYS_sigaltstack, vec![]),
|
||||
(libc::SYS_write, vec![]),
|
||||
(libc::SYS_writev, vec![]),
|
||||
])
|
||||
}
|
||||
|
||||
fn serial_manager_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
|
||||
Ok(vec![
|
||||
(libc::SYS_accept4, vec![]),
|
||||
@@ -1193,6 +1243,7 @@ fn get_seccomp_rules(
|
||||
Thread::DBusApi => dbus_api_thread_rules()?,
|
||||
Thread::EventMonitor => event_monitor_thread_rules()?,
|
||||
Thread::MigrationWorker => migration_thread_rules()?,
|
||||
Thread::MigrationTcpWorker => migration_tcp_worker_thread_rules()?,
|
||||
Thread::SerialManager => serial_manager_thread_rules()?,
|
||||
Thread::SignalHandler => signal_handler_thread_rules()?,
|
||||
Thread::Vcpu => vcpu_thread_rules(
|
||||
|
||||
Reference in New Issue
Block a user