# What Is the Role of Seccomp in CubeSandbox's Security Model?

> Seccomp secures CubeSandbox by whitelisting Linux syscalls, blocking unauthorized actions, and reducing kernel attack surface on the host.

- Repository: [Tencent Cloud/CubeSandbox](https://github.com/TencentCloud/CubeSandbox)
- Tags: internals
- Published: 2026-07-05

---

**Seccomp acts as the primary host-side sandboxing mechanism in CubeSandbox, enforcing per-thread whitelist of Linux syscalls to block unauthorized operations and minimize kernel attack surface.**

CubeSandbox, TencentCloud's open-source sandboxing solution, relies on seccomp (secure computing mode) to harden the Virtual Machine Monitor (VMM) process. By installing BPF filters that restrict which system calls each thread can invoke, the project implements a least-privilege security model that isolates guest workloads from the host operating system.

## Per-Thread Syscall Filtering

The security model applies **per-thread rule selection** rather than a global process policy. In [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs) (lines 21-28), the `Thread` enum defines distinct groups for the VMM process:

```rust
pub enum Thread {
    Api,
    SignalHandler,
    Vcpu,
    Vmm,
    PtyForeground,
    All,
}

```

Each variant maps to a specific vector of allowed syscalls. For example, the signal-handler thread receives only the minimal ioctls required for terminal management, while the VMM thread receives broader—but still strictly enumerated—rules for hypervisor operations. This separation ensures that a compromised API thread cannot invoke dangerous hypervisor commands reserved for the VMM thread.

## Hypervisor-Specific Rule Construction

Rules are constructed using the `and!` and `or!` macros (lines 35-46 in [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs)) to build complex `SeccompRule` objects. These rules match syscall numbers and arguments, such as allowing `ioctl` only with specific hypervisor-dependent request codes.

The functions `create_vmm_ioctl_seccomp_rule_common_kvm()` and `create_vmm_ioctl_seccomp_rule_common_mshv()` enumerate exact ioctl numbers permitted for KVM and MSHV respectively (lines 10-65):

```rust
fn create_vmm_ioctl_seccomp_rule_common_kvm() -> Vec<SeccompRule> {
    // Whitelist specific KVM ioctls
    vec![
        allow_ioctl(KVM_CREATE_VM),
        allow_ioctl(KVM_CREATE_VCPU),
        // ... additional allowed ioctls
    ]
}

```

This approach ensures that even if a guest compromises the VMM, it cannot invoke arbitrary hypervisor commands or escalate privileges through unapproved kernel interfaces.

## BPF Filter Generation and Application

The `thread_rules()` function (lines 440-574 in [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs)) aggregates rules for all thread types into a single vector of `(syscall, Vec<SeccompRule>)` tuples. The `get_seccomp_filter()` function (lines 998-1046) then translates these rules into a BPF program based on the configured **SeccompAction**:

- **Allow**: Permits the syscall (used for debugging)
- **Log**: Records violations without blocking (audit mode)
- **KillProcess**: Terminates the VMM immediately upon violation (production hardening)

When a VM initializes, `Vm::new_from_memory_manager()` stores the chosen action in `seccomp_action`. During startup or in `Vm::run()`, the filter is applied via `apply_filter(&filter)` (referenced in [`hypervisor/vmm/src/vm.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/vm.rs) lines 71-78):

```rust
impl Vm {
    fn run(&self) -> Result<()> {
        let filter = get_seccomp_filter(&self.seccomp_action, Thread::All, self.hypervisor_type)?;
        apply_filter(&filter)?;
        // VM execution proceeds under seccomp restrictions
    }
}

```

## Runtime Extensibility

CubeSandbox supports dynamic rule injection through `set_runtime_seccomp_rules()` (lines 776-782 in [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs)). This allows components like the Cubelet agent to append additional syscall allowances after the VM process has started, accommodating hot-plug devices or changing workload requirements without restarting the VMM.

## Code Examples

The following examples demonstrate how seccomp configuration flows from the orchestration layer down to the VMM implementation.

### Configuring Seccomp Action in Go

The Cubelet component specifies the enforcement level when creating a VM:

```go
cfg := cubepb.VmConfig{
    SeccompAction: cubepb.SeccompAction_KILL_PROCESS,
    // Additional configuration...
}
vm, err := cubelet.StartVm(cfg)

```

### Applying the Filter in Rust

The VMM receives the action and installs the filter:

```rust
use seccompiler::{apply_filter, SeccompAction};

fn apply_vm_seccomp(action: &SeccompAction, hypervisor: HypervisorType) -> Result<()> {
    let filter = get_seccomp_filter(action, Thread::All, hypervisor)?;
    apply_filter(&filter).map_err(|e| Error::ApplySeccompFilter(e))?;
    Ok(())
}

```

### Adding Runtime Rules

Components can inject additional allowances:

```rust
use hypervisor::vmm::seccomp_filters::{set_runtime_seccomp_rules, SeccompRule, SeccompCondition};

fn allow_runtime_ioctl() {
    let cond = SeccompCondition::new(1, ArgLen::Dword, Eq, KVM_IOCTL_MAGIC).unwrap();
    let rule = SeccompRule::new(vec![cond]).unwrap();
    set_runtime_seccomp_rules(vec![(libc::SYS_ioctl, vec![rule])]);
}

```

## Summary

- **Seccomp** provides the foundational host-side isolation in CubeSandbox by whitelisting syscalls per VMM thread.
- **Per-thread granularity** minimizes attack surfaces by restricting the signal-handler, API, and VCPU threads to only their essential operations.
- **Hypervisor-specific rules** in [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs) strictly control KVM and MSHV ioctl commands.
- **Configurable enforcement** via `SeccompAction` supports debugging (Allow), auditing (Log), and strict production modes (KillProcess).
- **Runtime extensibility** through `set_runtime_seccomp_rules()` enables dynamic security policy updates without VM restarts.

## Frequently Asked Questions

### What happens when CubeSandbox blocks a syscall?

When the seccomp filter encounters a non-whitelisted syscall, the configured `SeccompAction` determines the response. If set to **KillProcess** (the production default), the kernel immediately terminates the VMM process. If set to **Log**, the violation is recorded for auditing while the syscall returns an error code to the caller.

### Can seccomp rules be modified after a VM starts?

Yes. CubeSandbox exposes `set_runtime_seccomp_rules()` in [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs), allowing the Cubelet agent or other components to inject additional syscall rules into the global runtime list. These rules are merged into the filter during the next applicable thread execution, supporting hot-plug scenarios without requiring a VM restart.

### How does CubeSandbox handle different hypervisors like KVM versus MSHV?

The codebase defines hypervisor-specific rule constructors such as `create_vmm_ioctl_seccomp_rule_common_kvm()` and `create_vmm_ioctl_seccomp_rule_common_mshv()` in [`hypervisor/vmm/src/seccomp_filters.rs`](https://github.com/TencentCloud/CubeSandbox/blob/main/hypervisor/vmm/src/seccomp_filters.rs). Each function enumerates the exact ioctl numbers permitted for its respective hypervisor type, ensuring the VMM can only issue commands relevant to the underlying virtualization technology.

### Why does CubeSandbox use per-thread seccomp rules instead of a single process filter?

Different VMM threads have distinct responsibilities requiring different kernel interfaces. The signal-handler thread only needs terminal ioctls, while the VMM thread requires hypervisor-specific ioctls. By separating rules via the `Thread` enum, CubeSandbox applies the principle of least privilege—each thread can access only the minimal syscall set necessary for its function, reducing the blast radius of a compromised thread.