[PATCH] host/rootfs: Sandbox crosvm

Demi Marie Obenour
2025-11-29T22:34:43Z

This means that a breach of crosvm is not guaranteed to be fatal.

The Wayland socket is still only accessible by root, so crosvm must run
as root. The known container escape via /proc/self/exe is blocked by
bwrap being on a read-only filesystem. Container escapes via /proc are
blocked by remounting /proc read-only. Crosvm does not have
CAP_SYS_ADMIN so it cannot change mounts.

The two remaining steps are:

- Run crosvm as an unprivileged user.
- Enable seccomp to block most system calls.

The latter should be done from within crosvm itself.

Signed-off-by: Demi Marie Obenour <demiobenour@gmail.com>
---
host/rootfs/default.nix | 6 +++---
.../template/data/service/vhost-user-gpu/run | 17 ++++++++++++++++-
2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/host/rootfs/default.nix b/host/rootfs/default.nix
index b441a517f3bbb78f84d8566ca6dfd9181d0302be..81e12b6c2e98ca789d2d14e56dd2b7175296c1e8 100644
--- a/host/rootfs/default.nix
+++ b/host/rootfs/default.nix
@@ -10,7 +10,7 @@ pkgsMusl.callPackage (

{ spectrum-host-tools
, lib, stdenvNoCC, nixos, runCommand, writeClosure, erofs-utils, s6-rc
-, busybox, cloud-hypervisor, cosmic-files, crosvm, cryptsetup
+, bubblewrap, busybox, cloud-hypervisor, cosmic-files, crosvm, cryptsetup
, dejavu_fonts, dbus, execline, foot, fuse3, iproute2, inotify-tools
, jq, kmod, mdevd, mesa, s6, s6-linux-init, socat, systemd
, util-linuxMinimal, virtiofsd, westonLite, xdg-desktop-portal
@@ -25,8 +25,8 @@ let
trivial;

packages = [
- btrfs-progs cloud-hypervisor cosmic-files crosvm cryptsetup dbus
- execline fuse3 inotify-tools iproute2 jq kmod mdevd s6 s6-linux-init
+ bubblewrap btrfs-progs cloud-hypervisor cosmic-files crosvm cryptsetup
+ dbus execline fuse3 inotify-tools iproute2 jq kmod mdevd s6 s6-linux-init
s6-rc socat spectrum-host-tools util-linuxMinimal virtiofsd
xdg-desktop-portal-spectrum-host

diff --git a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run
index 0b4f6a00bc7aed0e721454d584d3bcd47fb18e2a..4838199a859cfadb45c23fb314f4651c6a6b3041 100755
--- a/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run
+++ b/host/rootfs/image/etc/s6-linux-init/run-image/service/vm-services/template/data/service/vhost-user-gpu/run
@@ -1,10 +1,25 @@
#!/bin/execlineb -P
# SPDX-License-Identifier: EUPL-1.2+
# SPDX-FileCopyrightText: 2025 Alyssa Ross <hi@alyssa.is>
+# SPDX-FileCopyrightText: 2025 Demi Marie Obenour <demiobenour@gmail.com>

s6-ipcserver -1a 0700 -C 1 -b 1 env/crosvm.sock

-crosvm --no-syslog device gpu
+bwrap
+ --unshare-all
+ --unshare-user
+ --bind /run/user/0/wayland-1 /run/user/0/wayland-1
+ --ro-bind /usr /usr
+ --ro-bind /lib /lib
+ --tmpfs /tmp
+ --dev /dev
+ --tmpfs /dev/shm
+ --ro-bind /nix /nix
+ --disable-userns
+ --proc /proc
+ --remount-ro /proc
+ --
+ crosvm --no-syslog device gpu
--fd 0
--wayland-sock /run/user/0/wayland-1
--params "{\"context-types\":\"cross-domain\"}"

---
base-commit: 965f5706764edb1b4fea147683b5ab803dd6df5e
change-id: 20251129-sandbox-5a42a6a41b59

--
Sincerely,
Demi Marie Obenour (she/her/hers)