Skip to content

Typestate Chain

The single most important safety mechanism in rustbox. It makes misordered sandbox setup a compile error, not a runtime bug.

Setting up a Linux sandbox requires doing things in a specific order. Namespaces before mounts. Mounts before cgroups. Cgroups before credential drop. Get the order wrong and you either break the sandbox or leave a security gap.

Every other sandbox enforces this through documentation, code review, or runtime checks. All of these can be bypassed by a tired developer at 2am.

Rust’s type system enforces the order at compile time:

Typestate chain

Only Sandbox<ExecReady> has an exec_payload() method. You literally cannot call it on any other state.

// This compiles:
let s = Sandbox::new(config); // FreshChild
let s = s.configure_namespaces()?; // NamespacesReady
let s = s.setup_mounts()?; // MountsPrivate
let s = s.attach_cgroup()?; // CgroupAttached
let s = s.drop_credentials()?; // CredsDropped
let s = s.lock_privileges()?; // PrivsLocked
s.exec_payload(cmd)?; // ExecReady ✓
// This doesn't compile:
let s = Sandbox::new(config);
s.exec_payload(cmd)?; // ✗ no method on Sandbox<FreshChild>
  • Can’t skip steps. Every transition is a required function call.
  • Can’t reorder. drop_credentials() only exists on Sandbox<CgroupAttached>.
  • Can’t go backwards. Each transition consumes self by value.
  • Verified by CI. Compile-fail tests confirm that wrong ordering produces the expected compiler error.
StateWhat happensKernel primitive
FreshChildProcess just clonedclone(2)
NamespacesReadyPID/mount/net/IPC configuredunshare(2)
MountsPrivateChroot, tmpfs, devices createdmount(2), chroot(2), mknod(2)
CgroupAttachedMemory/CPU/PID limits activecgroup filesystem writes
CredsDroppedUID/GID unprivileged, groups clearedsetresuid(2), setresgid(2)
PrivsLockedAll capabilities zeroed, NO_NEW_PRIVScapset(2), prctl(2)
ExecReadySeccomp filter installedseccomp(2)

Seccomp is installed last because the BPF filter would block syscalls needed for earlier stages (like mount and capset).