aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/sandbox
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-10-04 01:05:10 +0900
committerOphestra <cat@gensokyo.uk>2026-10-06 19:41:06 +0900
commita7383510fb05abc98b992240cb76ad4b6c598956 (patch)
tree90881e9d6952e050128f1378d66452c7d733d012 /test/sandbox
parentb452e1047ccd3e1826da16416430e6638270155b (diff)
test/sandbox: migrate tests
This significantly improves performance, removing overhead of nix, python, and virtualisation. Running this in an unprivileged container required patching the kernel, but since special runner setup was already needed, that was an acceptable tradeoff. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'test/sandbox')
-rw-r--r--test/sandbox/case/default.nix97
-rw-r--r--test/sandbox/case/device.nix255
-rw-r--r--test/sandbox/case/mapuid.nix282
-rw-r--r--test/sandbox/case/pd.nix206
-rw-r--r--test/sandbox/case/pdlike.nix277
-rw-r--r--test/sandbox/case/preset.nix274
-rw-r--r--test/sandbox/case/tty.nix288
-rw-r--r--test/sandbox/configuration.nix113
-rw-r--r--test/sandbox/default.nix41
-rw-r--r--test/sandbox/main.go410
-rw-r--r--test/sandbox/seccomp.patch18
-rw-r--r--test/sandbox/test.py88
-rw-r--r--test/sandbox/testdata/device.go134
-rw-r--r--test/sandbox/testdata/mapuid.go124
-rw-r--r--test/sandbox/testdata/pdlike.go141
-rw-r--r--test/sandbox/testdata/simple.go140
-rw-r--r--test/sandbox/testdata/sum.go22
-rw-r--r--test/sandbox/testdata/sum_amd64.go9
-rw-r--r--test/sandbox/testdata/sum_arm64.go9
-rw-r--r--test/sandbox/testdata/testdata.go125
-rw-r--r--test/sandbox/testdata/tty.go145
-rw-r--r--test/sandbox/tester/main.go224
-rw-r--r--test/sandbox/tool/main.go106
-rw-r--r--test/sandbox/tool/package.nix32
24 files changed, 1501 insertions, 2059 deletions
diff --git a/test/sandbox/case/default.nix b/test/sandbox/case/default.nix
deleted file mode 100644
index 337f4bf2..00000000
--- a/test/sandbox/case/default.nix
+++ /dev/null
@@ -1,97 +0,0 @@
-system: lib: testProgram:
-let
- fs = mode: dir: data: {
- mode = lib.fromHexString mode;
- inherit
- dir
- data
- ;
- };
-
- ignore = "//ignore";
-
- ent = root: target: vfs_optstr: fstype: source: fs_optstr: {
- id = -1;
- parent = -1;
- inherit
- root
- target
- vfs_optstr
- fstype
- source
- fs_optstr
- ;
- };
-
- importTestCase =
- path:
- import path {
- inherit
- fs
- ent
- ignore
- system
- ;
- };
-
- callTestCase =
- path: identity:
- let
- tc = importTestCase path;
- in
- {
- name = "check-sandbox-${tc.name}";
- inherit identity;
- verbose = true;
- inherit (tc)
- tty
- device
- mapRealUid
- useCommonPaths
- userns
- hostAbstract
- shareRuntime
- shareTmpdir
- ;
- enablements = {
- inherit (tc) x11;
- };
- share = testProgram;
- packages = [ ];
- path = "${testProgram}/bin/hakurei-test";
- args = [
- "hakurei-test"
- "-p"
- "/var/tmp/.hakurei-check-ok.${toString identity}"
- "-t"
- (toString (builtins.toFile "hakurei-${tc.name}-want.json" (builtins.toJSON tc.want)))
- "-s"
- tc.expectedFilter.${system}
- ];
-
- extraPaths =
- if tc.useCommonPaths then
- [ ]
- else
- [
- {
- type = "bind";
- src = "/var/tmp";
- write = true;
- }
- ];
- };
-
- testCaseName = name: "cat.gensokyo.hakurei.test." + name;
-in
-{
- apps = {
- ${testCaseName "preset"} = callTestCase ./preset.nix 1;
- ${testCaseName "tty"} = callTestCase ./tty.nix 2;
- ${testCaseName "mapuid"} = callTestCase ./mapuid.nix 3;
- ${testCaseName "device"} = callTestCase ./device.nix 4;
- ${testCaseName "pdlike"} = callTestCase ./pdlike.nix 5;
- };
-
- pd = importTestCase ./pd.nix;
-}
diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix
deleted file mode 100644
index 889e0a06..00000000
--- a/test/sandbox/case/device.nix
+++ /dev/null
@@ -1,255 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- sr = { };
- };
- };
-in
-{
- name = "device";
- tty = false;
- device = true;
- mapRealUid = false;
- useCommonPaths = true;
- userns = false;
- x11 = true;
- hostAbstract = false;
- shareRuntime = false;
- shareTmpdir = true;
-
- # 0, PresetStrict
- expectedFilter = {
- x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735";
- aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "DISPLAY=unix:/tmp/.X11-unix/X0"
- "HOME=/var/lib/hakurei/u0/a4"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a4"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- store = fs "800001ff" null null;
- } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" null null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a4:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a4:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001c0" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "800001f8" {
- ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null;
- } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a4 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- cache = fs "800001ed" { private = fs "800001c0" null null; } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10004,gid=10004")
- (ent "/" "/dev" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" ignore ignore ignore ignore ignore) # not deterministic
- (ent "/" ignore ignore ignore ignore ignore)
- (ent "/" ignore ignore ignore ignore ignore)
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10004,gid=10004")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10004,gid=10004")
- (ent "/tmp/hakurei.0/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10004,gid=10004")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr")
- (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = true;
- };
-}
diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix
deleted file mode 100644
index 1b6ef0e7..00000000
--- a/test/sandbox/case/mapuid.nix
+++ /dev/null
@@ -1,282 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "mapuid";
- tty = false;
- device = false;
- mapRealUid = true;
- useCommonPaths = true;
- userns = false;
- x11 = false;
- hostAbstract = false;
- shareRuntime = true;
- shareTmpdir = true;
-
- # 0, PresetStrict
- expectedFilter = {
- x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735";
- aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus"
- "HOME=/var/lib/hakurei/u0/a3"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a3"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/1000"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/1000/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- store = fs "800001ff" null null;
- } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:100:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a3:x:1000:100:Hakurei:/var/lib/hakurei/u0/a3:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "1000" = fs "800001f8" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "800001f8" { } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a3 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- cache = fs "800001ed" { private = fs "800001c0" null null; } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10003,gid=10003")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10003,gid=10003")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10003,gid=10003")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10003,gid=10003")
- (ent "/tmp/hakurei.0/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/hakurei.0/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10003,gid=10003")
- (ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr")
- (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,userxattr")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix
deleted file mode 100644
index 25f42979..00000000
--- a/test/sandbox/case/pd.nix
+++ /dev/null
@@ -1,206 +0,0 @@
-{
- fs,
- ent,
- ignore,
- ...
-}:
-{
- # 0, PresetExt | PresetDenyDevel
- expectedFilter = {
- x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a";
- aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980";
- };
-
- want = {
- env = [
- "HOME=/var/lib/hakurei/u0/a0"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=tty"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" { } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- console = fs "4200190" null null;
- core = fs "80001ff" null null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- kvm = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a0:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a0:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- home = fs "800001ed" { alice = fs "800001c0" null null; } null;
- lib64 = fs "800001ed" { "ld-linux-x86-64.so.2" = fs "80001ff" null null; } null;
- "lost+found" = fs "800001c0" null null;
- nix = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- ".rw-store" = fs "800001ed" null null;
- store = fs "801001fd" null null;
- var = fs "800001ed" {
- log = fs "800001ed" null null;
- nix = fs "800001ed" null null;
- } null;
- } null;
- proc = fs "8000016d" null null;
- root = fs "800001c0" null null;
- run = fs "800001ed" null null;
- srv = fs "800001ed" { } null;
- sys = fs "8000016d" null null;
- tmp = fs "800001f8" { } null;
- usr = fs "800001ed" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001ed" null null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
- (ent "/bin" "/bin" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/home" "/home" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/lib64" "/lib64" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/lost+found" "/lost+found" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/nix" "/nix" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- # systemd nondeterminism: ro-store rw-store
- (ent "/" ignore "rw,nosuid,nodev,relatime" ignore ignore ignore)
- (ent "/" ignore "rw,nosuid,nodev,relatime" ignore ignore ignore)
- (ent "/" "/nix/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/root" "/root" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/run" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore)
- (ent "/" "/run/keys" "rw,nosuid,nodev,relatime" "ramfs" "ramfs" "rw,mode=750")
- (ent "/" "/run/credentials/systemd-journald.service" "rw,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "none" "ro,size=1024k,nr_inodes=1024,mode=700,noswap")
- (ent "/" "/run/wrappers" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
- (ent "/" "/run/credentials/getty@tty1.service" "rw,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "none" "ro,size=1024k,nr_inodes=1024,mode=700,noswap")
- (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
- (ent "/srv" "/srv" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/sys" "rw,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/" "/sys/kernel/security" "rw,nosuid,nodev,noexec,relatime" "securityfs" "securityfs" "rw")
- (ent "/../../.." "/sys/fs/cgroup" "rw,nosuid,nodev,noexec,relatime" "cgroup2" "cgroup2" "rw,nsdelegate,memory_recursiveprot,memory_hugetlb_accounting")
- (ent "/" "/sys/fs/pstore" "rw,nosuid,nodev,noexec,relatime" "pstore" "none" "rw")
- (ent "/" "/sys/fs/bpf" "rw,nosuid,nodev,noexec,relatime" "bpf" "bpf" "rw,mode=700")
- # systemd nondeterminism: tracefs debugfs configfs fusectl
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
- (ent "/usr" "/usr" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var" "/var" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10000,gid=10000")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10000,gid=10000")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10000,gid=10000")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10000,gid=10000")
- (ent "/tmp/hakurei.0/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/hakurei.0/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10000,gid=10000")
- (ent "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
- (ent "/" "/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
- (ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=10000,gid=10000")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = true;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix
deleted file mode 100644
index 7f0716fb..00000000
--- a/test/sandbox/case/pdlike.nix
+++ /dev/null
@@ -1,277 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "pdlike";
- tty = true;
- device = false;
- mapRealUid = false;
- useCommonPaths = false;
- userns = true;
- x11 = false;
- hostAbstract = false;
- shareRuntime = true;
- shareTmpdir = true;
-
- # 0, PresetExt | PresetDenyDevel
- expectedFilter = {
- x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a";
- aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "HOME=/var/lib/hakurei/u0/a5"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a5"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" { } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- console = fs "4200190" null null;
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a5:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a5:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001f8" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "800001f8" { } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a5 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10005,gid=10005")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10005,gid=10005")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10005,gid=10005")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10005,gid=10005")
- (ent "/tmp/hakurei.0/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/hakurei.0/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10005,gid=10005")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix
deleted file mode 100644
index 33cc3b8b..00000000
--- a/test/sandbox/case/preset.nix
+++ /dev/null
@@ -1,274 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "preset";
- tty = false;
- device = false;
- mapRealUid = false;
- useCommonPaths = false;
- userns = false;
- x11 = false;
- hostAbstract = false;
- shareRuntime = false;
- shareTmpdir = false;
-
- # 0, PresetStrict
- expectedFilter = {
- x86_64-linux = "e880298df2bd6751d0040fc21bc0ed4c00f95dc0d7ba506c244d8b8cf6866dba8ef4a33296f287b66cccc1d78e97026597f84cc7dec1573e148960fbd35cd735";
- aarch64-linux = "79318538a3dc851314b6bd96f10d5861acb2aa7e13cb8de0619d0f6a76709d67f01ef3fd67e195862b02f9711e5b769bc4d1eb4fc0dfc41a723c89c968a93297";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "HOME=/var/lib/hakurei/u0/a1"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a1"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" { } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a1:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a1:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001c0" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "801001ff" { } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a1 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10001,gid=10001")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10001,gid=10001")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10001,gid=10001")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10001,gid=10001")
- (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10001,gid=10001")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10001,gid=10001")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = false;
- socket_pathname = false;
- };
-}
diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix
deleted file mode 100644
index 4ba9360e..00000000
--- a/test/sandbox/case/tty.nix
+++ /dev/null
@@ -1,288 +0,0 @@
-{
- fs,
- ent,
- ignore,
- system,
-}:
-let
- extraPaths = {
- x86_64-linux = {
- fd = "fd0";
- "/dev/dri" = {
- by-path = fs "800001ed" {
- "pci-0000:00:09.0-card" = fs "80001ff" null null;
- "pci-0000:00:09.0-render" = fs "80001ff" null null;
- } null;
- card0 = fs "42001b0" null null;
- renderD128 = fs "42001b6" null null;
- };
- sr = {
- sr0 = fs "80001ff" null null;
- };
- };
- aarch64-linux = {
- fd = "mtdblock0";
- "/dev/dri" = null;
- sr = { };
- };
- };
-in
-{
- name = "tty";
- tty = true;
- device = false;
- mapRealUid = false;
- useCommonPaths = true;
- userns = false;
- x11 = true;
- hostAbstract = true;
- shareRuntime = true;
- shareTmpdir = false;
-
- # 0, PresetExt | PresetDenyNS | PresetDenyDevel
- expectedFilter = {
- x86_64-linux = "0b76007476c1c9e25dbf674c29fdf609a1656a70063e49327654e1b5360ad3da06e1a3e32bf80e961c5516ad83d4b9e7e9bde876a93797e27627d2555c25858b";
- aarch64-linux = "cf1f4dc87436ba8ec95d268b663a6397bb0b4a5ac64d8557e6cc529d8b0f6f65dad3a92b62ed29d85eee9c6dde1267757a4d0f86032e8a45ca1bceadfa34cf5e";
- };
-
- want = {
- env = [
- "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus"
- "DISPLAY=:0"
- "HOME=/var/lib/hakurei/u0/a2"
- "SHELL=/run/current-system/sw/bin/bash"
- "TERM=linux"
- "USER=u0_a2"
- "WAYLAND_DISPLAY=wayland-0"
- "XDG_RUNTIME_DIR=/run/user/65534"
- "XDG_SESSION_CLASS=user"
- "XDG_SESSION_TYPE=wayland"
- "PULSE_SERVER=unix:/run/user/65534/pulse/native"
- ];
-
- fs = fs "dead" {
- ".hakurei" = fs "800001ed" {
- ".ro-store" = fs "801001fd" null null;
- store = fs "800001ff" null null;
- } null;
- bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
- dev = fs "800001ed" {
- console = fs "4200190" null null;
- core = fs "80001ff" null null;
- dri = fs "800001ed" extraPaths.${system}."/dev/dri" null;
- fd = fs "80001ff" null null;
- full = fs "42001b6" null null;
- mqueue = fs "801001ff" { } null;
- null = fs "42001b6" null "";
- ptmx = fs "80001ff" null null;
- pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
- random = fs "42001b6" null null;
- shm = fs "801001ff" { } null;
- stderr = fs "80001ff" null null;
- stdin = fs "80001ff" null null;
- stdout = fs "80001ff" null null;
- tty = fs "42001b6" null null;
- urandom = fs "42001b6" null null;
- zero = fs "42001b6" null null;
- } null;
- etc = fs "800001ed" {
- ".clean" = fs "80001ff" null null;
- ".host" = fs "800001c0" null null;
- ".updated" = fs "80001ff" null null;
- "NIXOS" = fs "80001ff" null null;
- "X11" = fs "80001ff" null null;
- "alsa" = fs "80001ff" null null;
- "bash_logout" = fs "80001ff" null null;
- "bashrc" = fs "80001ff" null null;
- "binfmt.d" = fs "80001ff" null null;
- "dbus-1" = fs "80001ff" null null;
- "default" = fs "80001ff" null null;
- "dhcpcd.exit-hook" = fs "80001ff" null null;
- "environment.d" = fs "80001ff" null null;
- "fonts" = fs "80001ff" null null;
- "fstab" = fs "80001ff" null null;
- "hsurc" = fs "80001ff" null null;
- "fuse.conf" = fs "80001ff" null null;
- "gai.conf" = fs "80001ff" null null;
- "group" = fs "180" null "hakurei:x:65534:\n";
- "host.conf" = fs "80001ff" null null;
- "hostname" = fs "80001ff" null null;
- "hosts" = fs "80001ff" null null;
- "inputrc" = fs "80001ff" null null;
- "issue" = fs "80001ff" null null;
- "kbd" = fs "80001ff" null null;
- "locale.conf" = fs "80001ff" null null;
- "login.defs" = fs "80001ff" null null;
- "lsb-release" = fs "80001ff" null null;
- "lvm" = fs "80001ff" null null;
- "machine-id" = fs "80001ff" null null;
- "man_db.conf" = fs "80001ff" null null;
- "modprobe.d" = fs "80001ff" null null;
- "modules-load.d" = fs "80001ff" null null;
- "mtab" = fs "80001ff" null null;
- "nanorc" = fs "80001ff" null null;
- "netgroup" = fs "80001ff" null null;
- "nix" = fs "80001ff" null null;
- "nixos" = fs "80001ff" null null;
- "nscd.conf" = fs "80001ff" null null;
- "nsswitch.conf" = fs "80001ff" null null;
- "os-release" = fs "80001ff" null null;
- "pam" = fs "80001ff" null null;
- "pam.d" = fs "80001ff" null null;
- "passwd" = fs "180" null "u0_a2:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a2:/run/current-system/sw/bin/bash\n";
- "pipewire" = fs "80001ff" null null;
- "pki" = fs "80001ff" null null;
- "polkit-1" = fs "80001ff" null null;
- "profile" = fs "80001ff" null null;
- "protocols" = fs "80001ff" null null;
- "resolv.conf" = fs "80001ff" null null;
- "resolvconf.conf" = fs "80001ff" null null;
- "rpc" = fs "80001ff" null null;
- "services" = fs "80001ff" null null;
- "set-environment" = fs "80001ff" null null;
- "shadow" = fs "80001ff" null null;
- "shells" = fs "80001ff" null null;
- "speech-dispatcher" = fs "80001ff" null null;
- "ssh" = fs "80001ff" null null;
- "ssl" = fs "80001ff" null null;
- "static" = fs "80001ff" null null;
- "subgid" = fs "80001ff" null null;
- "subuid" = fs "80001ff" null null;
- "sudoers" = fs "80001ff" null null;
- "sway" = fs "80001ff" null null;
- "sysctl.d" = fs "80001ff" null null;
- "systemd" = fs "80001ff" null null;
- "terminfo" = fs "80001ff" null null;
- "tmpfiles.d" = fs "80001ff" null null;
- "udev" = fs "80001ff" null null;
- "vconsole.conf" = fs "80001ff" null null;
- "xdg" = fs "80001ff" null null;
- "zoneinfo" = fs "80001ff" null null;
- } null;
- nix = fs "800001c0" { store = fs "801001fd" null null; } null;
- proc = fs "8000016d" null null;
- run = fs "800001ed" {
- current-system = fs "80001ff" null null;
- opengl-driver = fs "80001ff" null null;
- user = fs "800001ed" {
- "65534" = fs "800001f8" {
- bus = fs "10001fd" null null;
- pulse = fs "800001c0" { native = fs "10001ff" null null; } null;
- wayland-0 = fs "1000038" null null;
- } null;
- } null;
- } null;
- sys = fs "800001c0" {
- block = fs "800001ed" (
- {
- ${extraPaths.${system}.fd} = fs "80001ff" null null;
- loop0 = fs "80001ff" null null;
- loop1 = fs "80001ff" null null;
- loop2 = fs "80001ff" null null;
- loop3 = fs "80001ff" null null;
- loop4 = fs "80001ff" null null;
- loop5 = fs "80001ff" null null;
- loop6 = fs "80001ff" null null;
- loop7 = fs "80001ff" null null;
- vda = fs "80001ff" null null;
- }
- // extraPaths.${system}.sr
- ) null;
- bus = fs "800001ed" null null;
- class = fs "800001ed" null null;
- dev = fs "800001ed" {
- block = fs "800001ed" null null;
- char = fs "800001ed" null null;
- } null;
- devices = fs "800001ed" null null;
- } null;
- tmp = fs "801001ff" {
- ".X11-unix" = fs "801001ff" { X0 = fs "10001fd" null null; } null;
- } null;
- usr = fs "800001c0" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
- var = fs "800001c0" {
- tmp = fs "801001ff" null null;
- lib = fs "800001c0" {
- hakurei = fs "800001c0" {
- u0 = fs "800001c0" {
- a2 = fs "800001c0" {
- ".cache" = fs "800001ed" { ".keep" = fs "80001ff" null ""; } null;
- ".config" = fs "800001ed" {
- "environment.d" = fs "800001ed" { "10-home-manager.conf" = fs "80001ff" null null; } null;
- systemd = fs "800001ed" {
- user = fs "800001ed" { "tray.target" = fs "80001ff" null null; } null;
- } null;
- } null;
- ".local" = fs "800001ed" {
- state = fs "800001ed" {
- ".keep" = fs "80001ff" null "";
- home-manager = fs "800001ed" { gcroots = fs "800001ed" { current-home = fs "80001ff" null null; } null; } null;
- nix = fs "800001ed" {
- profiles = fs "800001ed" {
- profile = fs "80001ff" null null;
- profile-1-link = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- ".nix-defexpr" = fs "800001ed" {
- channels = fs "80001ff" null null;
- channels_root = fs "80001ff" null null;
- } null;
- ".nix-profile" = fs "80001ff" null null;
- } null;
- } null;
- } null;
- } null;
- cache = fs "800001ed" { private = fs "800001c0" null null; } null;
- } null;
- } null;
-
- mount = [
- (ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
- (ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
- (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=10002,gid=10002")
- (ent "/" "/dev" "ro,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=10002,gid=10002")
- (ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
- (ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
- (ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
- (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
- (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=16384k,mode=755,uid=10002,gid=10002")
- (ent "/tmp/hakurei.0/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/tmp" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=10002,gid=10002")
- (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
- (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=10002,gid=10002")
- (ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/tmp/.X11-unix" "/tmp/.X11-unix" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/sysroot/nix/.ro-store,upperdir=/sysroot/nix/.rw-store/upper,workdir=/sysroot/nix/.rw-store/work,uuid=on")
- (ent "/block" "/sys/block" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/bus" "/sys/bus" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/class" "/sys/class" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dev" "/sys/dev" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/devices" "/sys/devices" "ro,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
- (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
- (ent "/var/tmp" "/var/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/" "/.hakurei/.ro-store" "rw,relatime" "overlay" "overlay" "ro,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,redirect_dir=nofollow,userxattr")
- (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir+=/host/nix/.ro-store,lowerdir+=/host/nix/.rw-store/upper,upperdir=/host/tmp/.hakurei-store-rw/upper,workdir=/host/tmp/.hakurei-store-rw/work,redirect_dir=nofollow,uuid=on,userxattr")
- (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- (ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "ext4" "/dev/vda" "rw")
- ];
-
- seccomp = true;
-
- try_socket = "/tmp/.X11-unix/X0";
- socket_abstract = true;
- socket_pathname = true;
- };
-}
diff --git a/test/sandbox/configuration.nix b/test/sandbox/configuration.nix
deleted file mode 100644
index bc189f7d..00000000
--- a/test/sandbox/configuration.nix
+++ /dev/null
@@ -1,113 +0,0 @@
-{
- lib,
- pkgs,
- config,
- ...
-}:
-let
- testProgram = pkgs.callPackage ./tool/package.nix { inherit (config.environment.hakurei.package) version; };
- testCases = import ./case pkgs.stdenv.hostPlatform.system lib testProgram;
-in
-{
- users.users = {
- alice = {
- isNormalUser = true;
- description = "Alice Foobar";
- password = "foobar";
- uid = 1000;
- };
- };
-
- home-manager.users.alice.home.stateVersion = "24.11";
-
- # Automatically login on tty1 as a normal user:
- services.getty.autologinUser = "alice";
-
- environment = {
- systemPackages = [
- # For checking seccomp outcome:
- testProgram
-
- # For checking pd outcome:
- (pkgs.writeShellScriptBin "check-sandbox-pd" ''
- hakurei -v exec hakurei-test \
- -p "/var/tmp/.hakurei-check-ok.0" \
- -t ${toString (builtins.toFile "hakurei-pd-want.json" (builtins.toJSON testCases.pd.want))} \
- -s ${testCases.pd.expectedFilter.${pkgs.stdenv.hostPlatform.system}} "$@"
- '')
- ];
-
- variables = {
- SWAYSOCK = "/tmp/sway-ipc.sock";
- WLR_RENDERER = "pixman";
- };
- };
-
- # Automatically configure and start Sway when logging in on tty1:
- programs.bash.loginShellInit = ''
- if [ "$(tty)" = "/dev/tty1" ]; then
- set -e
-
- mkdir -p ~/.config/sway
- (sed s/Mod4/Mod1/ /etc/sway/config &&
- echo 'output * bg ${pkgs.nixos-artwork.wallpapers.simple-light-gray.gnomeFilePath} fill' &&
- echo 'output Virtual-1 res 1680x1050') > ~/.config/sway/config
-
- sway --validate
- systemd-cat --identifier=session sway && touch /tmp/sway-exit-ok
- fi
- '';
-
- programs.sway.enable = true;
-
- virtualisation.qemu.options = [
- # Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch:
- "-vga none -device virtio-gpu-pci"
-
- # Increase performance:
- "-smp 8"
- ];
-
- environment.hakurei = {
- enable = true;
- stateDir = "/var/lib/hakurei";
- users.alice = 0;
-
- extraHomeConfig = {
- home.stateVersion = "23.05";
- };
-
- commonPaths = [
- {
- type = "bind";
- src = "/var/tmp";
- write = true;
- }
- {
- type = "bind";
- src = "/var/cache";
- write = true;
- }
- {
- type = "overlay";
- dst = "/.hakurei/.ro-store";
- lower = [
- "/nix/.ro-store"
- "/nix/.rw-store/upper"
- ];
- }
- {
- type = "overlay";
- dst = "/.hakurei/store";
- lower = [
- "/nix/.ro-store"
- "/nix/.rw-store/upper"
- ];
- upper = "/tmp/.hakurei-store-rw/upper";
- work = "/tmp/.hakurei-store-rw/work";
- }
- ];
-
- inherit (testCases) apps;
- };
-}
diff --git a/test/sandbox/default.nix b/test/sandbox/default.nix
deleted file mode 100644
index 47a59de9..00000000
--- a/test/sandbox/default.nix
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- lib,
- testers,
-
- self,
- withRace ? false,
-}:
-
-testers.nixosTest {
- name = "hakurei-sandbox" + (if withRace then "-race" else "");
- nodes.machine =
- { options, pkgs, ... }:
- {
- # Run with Go race detector:
- environment.hakurei = lib.mkIf withRace rec {
- # race detector does not support static linking
- package = (pkgs.callPackage ../package.nix { }).overrideAttrs (previousAttrs: {
- env = previousAttrs.env // {
- GOFLAGS = previousAttrs.env.GOFLAGS + " -race";
- };
- });
- hsuPackage = options.environment.hakurei.hsuPackage.default.override { hakurei = package; };
- };
-
- imports = [
- ./configuration.nix
-
- self.nixosModules.hakurei
- self.inputs.home-manager.nixosModules.home-manager
- ];
- };
-
- # adapted from nixos sway integration tests
-
- # testScriptWithTypes:49: error: Cannot call function of unknown type
- # (machine.succeed if succeed else machine.execute)(
- # ^
- # Found 1 error in 1 file (checked 1 source file)
- skipTypeCheck = true;
- testScript = builtins.readFile ./test.py;
-}
diff --git a/test/sandbox/main.go b/test/sandbox/main.go
new file mode 100644
index 00000000..311b9f58
--- /dev/null
+++ b/test/sandbox/main.go
@@ -0,0 +1,410 @@
+//go:build testsuite
+
+// The sandbox test program runs cmd/hakurei with configurations simulating
+// several common workloads and inspects the resulting container states.
+package main
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "io"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "slices"
+ "strconv"
+ "strings"
+ "sync"
+ "sync/atomic"
+ "syscall"
+
+ "hakurei.app/check"
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/internal/store"
+
+ "hakurei.app/test/internal/testsuite"
+ "hakurei.app/test/sandbox/testdata"
+)
+
+// mustScanFor continuously scans the proc filesystem and calls f for each entry
+// visited.
+func mustScanFor(f func(ps *testsuite.StatScanner) bool) int {
+ var ps testsuite.StatScanner
+
+ for ps.Scan() {
+ if f(&ps) {
+ break
+ }
+ }
+ if err := ps.Err(); err != nil {
+ log.Fatal(err)
+ }
+ return ps.Stat().PID
+}
+
+// mustStart starts a hakurei container and returns the pid of a process within
+// the container. This process must be terminated by the caller.
+func mustStart(
+ ctx context.Context,
+ serial uint64,
+ username string,
+ files ...*os.File,
+) (pid int, done <-chan error) {
+ _serial := strconv.FormatUint(serial, 10)
+ _, done = testsuite.MustStartAs(
+ ctx, username, files,
+ "hakurei", "exec",
+ "sleep", "infinity", _serial,
+ )
+
+ var stat syscall.Stat_t
+ pid = mustScanFor(func(s *testsuite.StatScanner) bool {
+ select {
+ case err := <-done:
+ if err == nil {
+ log.Fatal("test process terminated unexpectedly")
+ }
+ log.Fatal(err)
+ default:
+ break
+ }
+
+ if s.Stat().Comm != "sleep" {
+ return false
+ }
+
+ if args, err := s.Stat().Args(); err != nil {
+ if testsuite.IsNotExist(err) {
+ return false
+ }
+ log.Fatal(err)
+ } else if !slices.Equal(args, []string{
+ "sleep",
+ "infinity",
+ _serial,
+ }) {
+ return false
+ }
+
+ if err := s.Stat().Stat(&stat); err != nil {
+ if testsuite.IsNotExist(err) {
+ return false
+ }
+ log.Fatal(err)
+ }
+
+ id := hst.ToUser[uint32](0, 0)
+ if stat.Uid != id || stat.Gid != id {
+ return false
+ }
+
+ return true
+ })
+ return
+}
+
+func main() {
+ go testsuite.ReceiveSignals()
+ username := testsuite.GetUser().Username
+
+ // the signal handler does not wait for termination
+ ctx := context.Background()
+
+ if err := os.MkdirAll("/opt/test-helper/bin", 0755); err != nil {
+ log.Fatal(err)
+ }
+
+ var testToolDone <-chan error
+ {
+ cmd := exec.Command(
+ "go", "build",
+ "-o", "/opt/test-helper/bin",
+ "-tags=tester",
+ "-trimpath",
+ "./test/sandbox/tester",
+ )
+ cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
+ testToolDone = testsuite.MustStart(cmd)
+ }
+
+ var wg sync.WaitGroup
+ defer wg.Wait()
+
+ var serial atomic.Uint64
+ newSerial := func() uint64 { serial.Add(1); return serial.Load() }
+
+ testsuite.MustRunAs(
+ username, "-i",
+ "hakurei", "exec", "capsh", "--print",
+ )
+ wg.Go(func() {
+ defer log.Println("validated capabilities/securebits in user namespace")
+
+ testsuite.MustRunAs(
+ username, "-i",
+ "hakurei", "exec", "capsh", "--has-no-new-privs",
+ )
+
+ for _, p := range []byte{'a', 'b', 'i', 'p'} {
+ testsuite.MustFailAs(
+ username, "-i",
+ "hakurei", "exec", "capsh", "--has-"+string(p)+"=CAP_SYS_ADMIN",
+ )
+ }
+ testsuite.MustFailAs(
+ username, "-i",
+ "hakurei", "exec", "umount", "-R", "/dev",
+ )
+ })
+
+ wg.Go(func() {
+ defer log.Println("validated pd seccomp outcome")
+
+ c, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ pid, done := mustStart(c, newSerial(), username)
+ testsuite.MustCheckFilter(pid, testdata.SumPD)
+ if err := testsuite.FilterTerminated(<-done); err != nil {
+ log.Fatal(err)
+ }
+ })
+
+ wg.Go(func() {
+ defer log.Println("validated fd leak")
+
+ c, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ pid, done := mustStart(c, newSerial(), username, os.Stdin, os.Stdout, os.Stderr)
+ prefix := filepath.Join(fhs.Proc, strconv.Itoa(pid), "fd")
+
+ var fail bool
+ if entries, err := os.ReadDir(prefix); err != nil {
+ log.Fatal(err.Error())
+ } else {
+ for _, ent := range entries {
+ var fd int
+ if fd, err = strconv.Atoi(ent.Name()); err != nil {
+ log.Fatal(err.Error())
+ }
+
+ // skip standard streams
+ if fd <= 2 {
+ continue
+ }
+ fail = true
+
+ var d string
+ if d, err = os.Readlink(filepath.Join(
+ prefix,
+ ent.Name(),
+ )); err != nil {
+ log.Fatal(err.Error())
+ }
+ log.Printf("extra fd %d -> %s", fd, d)
+ }
+ }
+ if fail {
+ log.Fatal("file descriptors leaked")
+ }
+
+ if err := syscall.Kill(pid, syscall.SIGTERM); err != nil {
+ log.Fatalf("cannot terminate anchor: %v", err)
+ } else if err = testsuite.FilterTerminated(<-done); err != nil {
+ log.Fatal(err)
+ }
+ })
+
+ if err := os.MkdirAll(testsuite.XDGRuntimeDir, 0700); err != nil {
+ log.Fatal(err)
+ } else if err = os.Chown(testsuite.XDGRuntimeDir, 1000, 1000); err != nil {
+ log.Fatal(err)
+ }
+
+ var swg sync.WaitGroup
+ defer swg.Wait()
+ dbusEnv := testsuite.MustStartSessionBus(username)
+ testsuite.MustStartSway(&swg, username, dbusEnv)
+ defer testsuite.TerminateSway(username)
+ testsuite.MustStartPipeWire(username, dbusEnv)
+
+ if err := <-testToolDone; err != nil {
+ log.Fatal(err)
+ }
+ log.Println("created test helper")
+
+ s := store.New(check.MustAbs("/tmp/hakurei.0/state"))
+ for name, tc := range testdata.All() {
+ wg.Go(func() {
+ cmd := exec.Command(
+ "sudo",
+ "-u", username,
+ "-C", "6",
+ "TERM=xterm",
+ testsuite.XDGRuntimeEnv,
+ testsuite.WaylandEnv,
+ "DISPLAY=:0",
+ dbusEnv,
+ "--",
+
+ "script", "/dev/null",
+ "-E", "always",
+ "-qec",
+ "hakurei run "+
+ "--identifier-fd=5"+
+ " 4 1>&3",
+ )
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGTERM,
+ }
+ var output bytes.Buffer
+ cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, &output, &output
+
+ var err error
+ var notify, _notify, _conf, conf, ident, _ident *os.File
+ if notify, _notify, err = os.Pipe(); err != nil {
+ log.Fatal(err)
+ }
+ cmd.ExtraFiles = append(cmd.ExtraFiles, _notify)
+ if _conf, conf, err = os.Pipe(); err != nil {
+ log.Fatal(err)
+ }
+ cmd.ExtraFiles = append(cmd.ExtraFiles, _conf)
+ if ident, _ident, err = os.Pipe(); err != nil {
+ log.Fatal(err)
+ }
+ cmd.ExtraFiles = append(cmd.ExtraFiles, _ident)
+
+ done := testsuite.MustStart(cmd)
+ wg.Go(func() {
+ _err := <-done
+ log.Printf("completed test case %s\n%s", name, output.String())
+ if _err != nil {
+ log.Fatalf("test case %s: %v", name, _err)
+ }
+ })
+
+ if err = json.NewEncoder(conf).Encode(&tc.Hakurei); err != nil {
+ log.Fatal(err)
+ } else if err = conf.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ var id hst.ID
+ if _, err = io.ReadFull(ident, id[:]); err != nil {
+ log.Fatal(err)
+ } else if err = ident.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ if _, err = io.ReadFull(notify, make([]byte, 8)); err != nil {
+ log.Fatal(err)
+ } else if err = notify.Close(); err != nil {
+ log.Fatal(err)
+ }
+
+ var (
+ ok bool
+ p hst.State
+ )
+ entries, copyError := s.All()
+ for entry := range entries {
+ if entry.ID == id {
+ ok = true
+ if _, err = entry.Load(&p, nil); err != nil {
+ log.Fatal(err)
+ }
+ break
+ }
+ }
+ if err = copyError(); err != nil {
+ log.Fatal(err)
+ }
+ if !ok {
+ log.Fatalf("instance %s is not present in store", id)
+ }
+
+ var stat syscall.Stat_t
+ pid := mustScanFor(func(ps *testsuite.StatScanner) bool {
+ select {
+ case err = <-done:
+ if err == nil {
+ log.Fatal("test process terminated unexpectedly")
+ }
+ log.Fatal(err)
+ default:
+ break
+ }
+
+ if ps.Stat().Comm != "test-helper" {
+ return false
+ }
+
+ var args []string
+ if args, err = ps.Stat().Args(); err != nil {
+ if testsuite.IsNotExist(err) {
+ return false
+ }
+ log.Fatal(err)
+ } else if !slices.Equal(args, tc.Hakurei.Container.Args) {
+ return false
+ }
+
+ if err = ps.Stat().Stat(&stat); err != nil {
+ if testsuite.IsNotExist(err) {
+ return false
+ }
+ log.Fatal(err)
+ }
+
+ uid := hst.ToUser[uint32](0, uint32(tc.Hakurei.Identity))
+ if stat.Uid != uid || stat.Gid != uid {
+ return false
+ }
+
+ var t []byte
+ if t, err = os.ReadFile(filepath.Join(
+ fhs.Proc,
+ strconv.Itoa(ps.Stat().PPID),
+ "stat",
+ )); err != nil {
+ if testsuite.IsNotExist(err) {
+ return false
+ }
+ log.Fatal(err)
+ }
+
+ var _stat testsuite.Stat
+ if err = _stat.UnmarshalText(t); err != nil {
+ log.Fatal(err)
+ }
+ if _stat.PPID != p.ShimPID {
+ return false
+ }
+
+ return true
+ })
+
+ testsuite.MustCheckFilter(
+ pid,
+ tc.Sum,
+ )
+ })
+ }
+
+ wg.Wait()
+
+ if dents, err := os.ReadDir("/tmp"); err != nil {
+ log.Fatal(err)
+ } else {
+ for _, dent := range dents {
+ if name := dent.Name(); strings.HasPrefix(name, ".hakurei-shim-") {
+ log.Fatalf("leftover shim work dir %q", name)
+ }
+ }
+ }
+}
diff --git a/test/sandbox/seccomp.patch b/test/sandbox/seccomp.patch
new file mode 100644
index 00000000..ddabc71e
--- /dev/null
+++ b/test/sandbox/seccomp.patch
@@ -0,0 +1,18 @@
+diff --git a/kernel/seccomp.c b/kernel/seccomp.c
+index 25f62867a16d..7b63ccc8daf4 100644
+--- a/kernel/seccomp.c
++++ b/kernel/seccomp.c
+@@ -2216,8 +2216,12 @@ long seccomp_get_filter(struct task_struct *task, unsigned long filter_off,
+ struct seccomp_filter *filter;
+ struct sock_fprog_kern *fprog;
+ long ret;
++ struct user_namespace *user_ns = current_user_ns();
+
+- if (!capable(CAP_SYS_ADMIN) ||
++ if (in_userns(user_ns, task_cred_xxx(task, user_ns))) {
++ if (!ns_capable(user_ns, CAP_SYS_ADMIN))
++ return -EACCES;
++ } else if (!capable(CAP_SYS_ADMIN) ||
+ current->seccomp.mode != SECCOMP_MODE_DISABLED) {
+ return -EACCES;
+ }
diff --git a/test/sandbox/test.py b/test/sandbox/test.py
deleted file mode 100644
index a431daab..00000000
--- a/test/sandbox/test.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import json
-import shlex
-
-q = shlex.quote
-
-
-def swaymsg(command: str = "", succeed=True, type="command"):
- assert command != "" or type != "command", "Must specify command or type"
- shell = q(f"swaymsg -t {q(type)} -- {q(command)}")
- with machine.nested(
- f"sending swaymsg {shell!r}" + " (allowed to fail)" * (not succeed)
- ):
- ret = (machine.succeed if succeed else machine.execute)(
- f"su - alice -c {shell}"
- )
-
- # execute also returns a status code, but disregard.
- if not succeed:
- _, ret = ret
-
- if not succeed and not ret:
- return None
-
- parsed = json.loads(ret)
- return parsed
-
-
-def check_filter(check_offset, name, pname):
- pid = int(machine.wait_until_succeeds(f"pgrep -U {10000+check_offset} -x {pname}"))
- hash = machine.succeed(f"sudo -u alice -i XDG_RUNTIME_DIR=/run/user/1000 WAYLAND_DISPLAY=wayland-1 check-sandbox-{name} hash")
- print(machine.succeed(f"hakurei-test -s {hash} filter {pid}"))
-
-
-start_all()
-machine.wait_for_unit("multi-user.target")
-
-# To check hakurei's version:
-print(machine.succeed("sudo -u alice -i hakurei version"))
-
-# Wait for Sway to complete startup:
-machine.wait_for_file("/run/user/1000/wayland-1")
-machine.wait_for_file("/tmp/sway-ipc.sock")
-
-# Check pd seccomp outcome:
-swaymsg("exec hakurei exec cat")
-check_filter(0, "pdlike", "cat")
-
-# Check fd leak:
-swaymsg("exec exec 127</proc/cmdline && hakurei -v exec sleep infinity")
-pd_identity0_sleep_pid = int(machine.wait_until_succeeds("pgrep -U 10000 -x sleep"))
-print(machine.succeed(f"hakurei-test fd {pd_identity0_sleep_pid}"))
-machine.succeed(f"kill -INT {pd_identity0_sleep_pid}")
-
-# Verify capabilities/securebits in user namespace:
-print(machine.succeed("sudo -u alice -i hakurei exec capsh --print"))
-print(machine.succeed("sudo -u alice -i hakurei exec capsh --has-no-new-privs"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-a=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-b=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-i=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec capsh --has-p=CAP_SYS_ADMIN"))
-print(machine.fail("sudo -u alice -i hakurei exec umount -R /dev"))
-
-# Check sandbox outcome:
-machine.succeed("install -dm0777 /tmp/.hakurei-store-rw/{upper,work}")
-check_offset = 0
-def check_sandbox(name):
- global check_offset
- swaymsg(f"exec script /dev/null -E always -qec check-sandbox-{name}")
- machine.wait_for_file(f"/var/tmp/.hakurei-check-ok.{check_offset}")
- check_filter(check_offset, name, "hakurei-test")
- check_offset += 1
-
-
-check_sandbox("pd")
-check_sandbox("preset")
-check_sandbox("tty")
-check_sandbox("mapuid")
-check_sandbox("device")
-check_sandbox("pdlike")
-
-# Exit Sway and verify process exit status 0:
-machine.wait_until_fails("pgrep -x hakurei")
-swaymsg("exit", succeed=False)
-machine.wait_for_file("/tmp/sway-exit-ok")
-
-# Print hakurei runDir contents:
-print(machine.fail("ls /run/user/1000/hakurei"))
-machine.succeed("find /tmp -maxdepth 1 -type d -name '.hakurei-shim-*' -print -exec false '{}' +")
diff --git a/test/sandbox/testdata/device.go b/test/sandbox/testdata/device.go
new file mode 100644
index 00000000..89feb819
--- /dev/null
+++ b/test/sandbox/testdata/device.go
@@ -0,0 +1,134 @@
+//go:build testsuite || tester
+
+package testdata
+
+import (
+ "os"
+ "syscall"
+
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/internal/testsuite"
+)
+
+var _ = TestCase{
+ Hakurei: hst.Config{
+ ID: "app.hakurei.sample.device",
+ Enablements: new(hst.EWayland | hst.EPipeWire | hst.EDBus | hst.EX11),
+ Identity: 4,
+
+ Container: &hst.ContainerConfig{
+ Hostname: "hakurei-sample-device",
+
+ Filesystem: []hst.FilesystemConfigJSON{
+ fcLinker,
+ fcLib,
+ fcTestHelper,
+ },
+
+ Username: "u0_a4",
+ Shell: fhs.AbsUsrBin.Append("bash"),
+ Home: hst.AbsPrivateTmp,
+ Path: absTestHelper,
+ Args: []string{"tester", "device"},
+
+ Flags: hst.FDevice | hst.FShareTmpdir,
+ },
+ },
+
+ // 0, PresetStrict
+ Sum: sumSimple,
+
+ Env: []string{
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus",
+ "DISPLAY=unix:/tmp/.X11-unix/X0",
+ "HOME=/.hakurei",
+ "SHELL=/usr/bin/bash",
+ "TERM=xterm",
+ "USER=u0_a4",
+ "WAYLAND_DISPLAY=wayland-0",
+ "XDG_RUNTIME_DIR=/run/user/65534",
+ "XDG_SESSION_CLASS=user",
+ "XDG_SESSION_TYPE=wayland",
+ "PULSE_SERVER=unix:/run/user/65534/pulse/native",
+ },
+
+ FS: &testsuite.FS{Dir: dir{
+ ".hakurei": {Mode: os.ModeDir | 0755, Dir: dir{
+ "test-helper": {Mode: 0755},
+ }},
+
+ // unstable host dev
+ "dev": {Mode: os.ModeDir | 0755},
+
+ "etc": {Mode: os.ModeDir | 0755, Dir: dir{
+ "passwd": {Mode: 0600,
+ Data: new("u0_a4:x:65534:65534:Hakurei:/.hakurei:/usr/bin/bash\n")},
+ "group": {Mode: 0600,
+ Data: new("hakurei:x:65534:\n")},
+ }},
+
+ "lib64": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ld-linux-x86-64.so.2": {Mode: os.ModeSymlink | 0777},
+ }},
+
+ "run": {Mode: os.ModeDir | 0755, Dir: dir{
+ "user": {Mode: os.ModeDir | 0755, Dir: dir{
+ "65534": {Mode: os.ModeDir | 0700, Dir: dir{
+ "bus": {Mode: os.ModeSocket | 0775},
+ "wayland-0": {Mode: os.ModeSocket | 070},
+ "pulse": {Mode: os.ModeDir | 0700, Dir: dir{
+ "native": {Mode: os.ModeSocket | 0777},
+ }},
+ }},
+ }},
+ }},
+
+ "tmp": {Mode: os.ModeDir | 0770, Dir: dir{
+ ".X11-unix": {Mode: os.ModeDir | 0755, Dir: dir{
+ "X0": {Mode: os.ModeSocket | 0775},
+ }},
+ }},
+
+ "lib": {Mode: os.ModeDir | 0755},
+ "proc": {Mode: os.ModeDir | 0555},
+ }},
+
+ Mount: []*mountinfo.Entry{
+ r("/sysroot", "/", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110003,gid=110003,inode64"),
+ r("/", "/proc", "rw,nosuid,nodev,noexec,relatime", "proc", "proc", "rw"),
+ r("/", "/.hakurei", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=4k,mode=755,uid=110003,gid=110003,inode64"),
+
+ // host /dev in testing environment
+ r("/", "/dev", "rw,nosuid", "tmpfs", "tmpfs", ignore),
+ r("/", "/dev/pts", "rw,nosuid,noexec,relatime", "devpts", "devpts", "rw,gid=100004,mode=620,ptmxmode=666"),
+ r("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
+ r("/kvm", "/dev/kvm", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/fuse", "/dev/fuse", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/", "/dev/shm", "rw,nosuid,nodev,noexec,relatime", "tmpfs", "shm", ignore),
+ r("/null", "/dev/null", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/zero", "/dev/zero", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/full", "/dev/full", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/tty", "/dev/tty", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/random", "/dev/random", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/urandom", "/dev/urandom", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+
+ r("/", "/dev/shm", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110003,gid=110003,inode64"),
+ r("/", "/run/user", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=16384k,mode=755,uid=110003,gid=110003,inode64"),
+ r("/tmp/hakurei.0/tmpdir/4", "/tmp", "rw,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/etc/passwd", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110003,gid=110003,inode64"),
+ r(ignore, "/etc/group", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110003,gid=110003,inode64"),
+ r(ignore, "/run/user/65534/wayland-0", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/tmp/.X11-unix", "/tmp/.X11-unix", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/bus", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/usr/lib", "/lib", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/opt/test-helper/bin/tester", "/.hakurei/test-helper", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/pulse/native", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ },
+
+ Seccomp: true,
+
+ TrySocket: "/tmp/.X11-unix/X0",
+ ErrnoAbstract: syscall.ECONNREFUSED,
+}.register("device")
diff --git a/test/sandbox/testdata/mapuid.go b/test/sandbox/testdata/mapuid.go
new file mode 100644
index 00000000..fad4ec36
--- /dev/null
+++ b/test/sandbox/testdata/mapuid.go
@@ -0,0 +1,124 @@
+//go:build testsuite || tester
+
+package testdata
+
+import (
+ "os"
+ "syscall"
+
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/internal/testsuite"
+)
+
+var _ = TestCase{
+ Hakurei: hst.Config{
+ ID: "app.hakurei.sample.mapuid",
+ Enablements: new(hst.EWayland | hst.EPipeWire | hst.EDBus),
+ Identity: 3,
+
+ Container: &hst.ContainerConfig{
+ Hostname: "hakurei-sample-mapuid",
+
+ Filesystem: []hst.FilesystemConfigJSON{
+ fcLinker,
+ fcLib,
+ fcTestHelper,
+ },
+
+ Username: "u0_a3",
+ Shell: fhs.AbsUsrBin.Append("bash"),
+ Home: hst.AbsPrivateTmp,
+ Path: absTestHelper,
+ Args: []string{"tester", "mapuid"},
+
+ Flags: hst.FMapRealUID | hst.FShareRuntime | hst.FShareTmpdir,
+ },
+ },
+
+ // 0, PresetStrict
+ Sum: sumSimple,
+
+ Env: []string{
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus",
+ "HOME=/.hakurei",
+ "SHELL=/usr/bin/bash",
+ "TERM=xterm",
+ "USER=u0_a3",
+ "WAYLAND_DISPLAY=wayland-0",
+ "XDG_RUNTIME_DIR=/run/user/1000",
+ "XDG_SESSION_CLASS=user",
+ "XDG_SESSION_TYPE=wayland",
+ "PULSE_SERVER=unix:/run/user/1000/pulse/native",
+ },
+
+ FS: &testsuite.FS{Dir: dir{
+ ".hakurei": {Mode: os.ModeDir | 0755, Dir: dir{
+ "test-helper": {Mode: 0755},
+ }},
+
+ // unstable host dev
+ "dev": {Mode: os.ModeDir | 0755},
+
+ "etc": {Mode: os.ModeDir | 0755, Dir: dir{
+ "passwd": {Mode: 0600,
+ Data: new("u0_a3:x:1000:1000:Hakurei:/.hakurei:/usr/bin/bash\n")},
+ "group": {Mode: 0600,
+ Data: new("hakurei:x:1000:\n")},
+ }},
+
+ "lib64": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ld-linux-x86-64.so.2": {Mode: os.ModeSymlink | 0777},
+ }},
+
+ "run": {Mode: os.ModeDir | 0755, Dir: dir{
+ "user": {Mode: os.ModeDir | 0755, Dir: dir{
+ "1000": {Mode: os.ModeDir | 0770, Dir: dir{
+ "bus": {Mode: os.ModeSocket | 0775},
+ "wayland-0": {Mode: os.ModeSocket | 070},
+ "pulse": {Mode: os.ModeDir | 0700, Dir: dir{
+ "native": {Mode: os.ModeSocket | 0777},
+ }},
+ }},
+ }},
+ }},
+
+ "tmp": {Mode: os.ModeDir | 0770, Dir: dir{}},
+
+ "lib": {Mode: os.ModeDir | 0755},
+ "proc": {Mode: os.ModeDir | 0555},
+ }},
+
+ Mount: []*mountinfo.Entry{
+ r("/sysroot", "/", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110002,gid=110002,inode64"),
+ r("/", "/proc", "rw,nosuid,nodev,noexec,relatime", "proc", "proc", "rw"),
+ r("/", "/.hakurei", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=4k,mode=755,uid=110002,gid=110002,inode64"),
+ r("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", "rw,mode=755,uid=110002,gid=110002,inode64"),
+ r("/null", "/dev/null", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/zero", "/dev/zero", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/full", "/dev/full", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/random", "/dev/random", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/urandom", "/dev/urandom", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/tty", "/dev/tty", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/", "/dev/pts", "rw,nosuid,noexec,relatime", "devpts", "devpts", "rw,mode=620,ptmxmode=666"),
+ r("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
+ r("/", "/dev/shm", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110002,gid=110002,inode64"),
+ r("/", "/run/user", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=16384k,mode=755,uid=110002,gid=110002,inode64"),
+ r("/tmp/hakurei.0/runtime/3", "/run/user/1000", "rw,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/tmp/hakurei.0/tmpdir/3", "/tmp", "rw,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/etc/passwd", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110002,gid=110002,inode64"),
+ r(ignore, "/etc/group", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110002,gid=110002,inode64"),
+ r(ignore, "/run/user/1000/wayland-0", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/1000/bus", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/usr/lib", "/lib", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/opt/test-helper/bin/tester", "/.hakurei/test-helper", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/1000/pulse/native", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ },
+
+ Seccomp: true,
+
+ TrySocket: "/tmp/.X11-unix/X0",
+ ErrnoAbstract: syscall.ECONNREFUSED,
+ ErrnoPathname: syscall.ENOENT,
+}.register("mapuid")
diff --git a/test/sandbox/testdata/pdlike.go b/test/sandbox/testdata/pdlike.go
new file mode 100644
index 00000000..53d8062a
--- /dev/null
+++ b/test/sandbox/testdata/pdlike.go
@@ -0,0 +1,141 @@
+//go:build testsuite || tester
+
+package testdata
+
+import (
+ "os"
+ "syscall"
+
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/internal/testsuite"
+)
+
+var _ = TestCase{
+ Hakurei: hst.Config{
+ ID: "app.hakurei.sample.pdlike",
+ Enablements: new(hst.EWayland | hst.EPipeWire | hst.EDBus),
+ Identity: 5,
+
+ Container: &hst.ContainerConfig{
+ Hostname: "hakurei-sample-pdlike",
+
+ Filesystem: []hst.FilesystemConfigJSON{
+ fcLinker,
+ fcLib,
+ fcTestHelper,
+ },
+
+ Username: "u0_a5",
+ Shell: fhs.AbsUsrBin.Append("bash"),
+ Home: hst.AbsPrivateTmp,
+ Path: absTestHelper,
+ Args: []string{"tester", "pdlike"},
+
+ Flags: hst.FHostNet | hst.FTty | hst.FUserns | hst.FShareRuntime | hst.FShareTmpdir,
+ },
+ },
+
+ // 0, PresetExt | PresetDenyDevel
+ Sum: SumPD,
+
+ Env: []string{
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus",
+ "HOME=/.hakurei",
+ "SHELL=/usr/bin/bash",
+ "TERM=xterm",
+ "USER=u0_a5",
+ "WAYLAND_DISPLAY=wayland-0",
+ "XDG_RUNTIME_DIR=/run/user/65534",
+ "XDG_SESSION_CLASS=user",
+ "XDG_SESSION_TYPE=wayland",
+ "PULSE_SERVER=unix:/run/user/65534/pulse/native",
+ },
+
+ FS: &testsuite.FS{Dir: dir{
+ ".hakurei": {Mode: os.ModeDir | 0755, Dir: dir{
+ "test-helper": {Mode: 0755},
+ }},
+
+ "dev": {Mode: os.ModeDir | 0755, Dir: dir{
+ "core": {Mode: os.ModeSymlink | 0777},
+ "fd": {Mode: os.ModeSymlink | 0777},
+ "full": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "mqueue": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+ "null": {Mode: os.ModeDevice | os.ModeCharDevice | 0666, Data: new("")},
+ "ptmx": {Mode: os.ModeSymlink | 0777},
+ "pts": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ptmx": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ }},
+ "random": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "shm": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+ "stderr": {Mode: os.ModeSymlink | 0777},
+ "stdin": {Mode: os.ModeSymlink | 0777},
+ "stdout": {Mode: os.ModeSymlink | 0777},
+ "tty": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "urandom": {Mode: os.ModeDevice | os.ModeCharDevice | 0444},
+ "zero": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ }},
+
+ "etc": {Mode: os.ModeDir | 0755, Dir: dir{
+ "passwd": {Mode: 0600,
+ Data: new("u0_a5:x:65534:65534:Hakurei:/.hakurei:/usr/bin/bash\n")},
+ "group": {Mode: 0600,
+ Data: new("hakurei:x:65534:\n")},
+ }},
+
+ "lib64": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ld-linux-x86-64.so.2": {Mode: os.ModeSymlink | 0777},
+ }},
+
+ "run": {Mode: os.ModeDir | 0755, Dir: dir{
+ "user": {Mode: os.ModeDir | 0755, Dir: dir{
+ "65534": {Mode: os.ModeDir | 0770, Dir: dir{
+ "bus": {Mode: os.ModeSocket | 0775},
+ "wayland-0": {Mode: os.ModeSocket | 070},
+ "pulse": {Mode: os.ModeDir | 0700, Dir: dir{
+ "native": {Mode: os.ModeSocket | 0777},
+ }},
+ }},
+ }},
+ }},
+
+ "tmp": {Mode: os.ModeDir | 0770, Dir: dir{}},
+
+ "lib": {Mode: os.ModeDir | 0755},
+ "proc": {Mode: os.ModeDir | 0555},
+ }},
+
+ Mount: []*mountinfo.Entry{
+ r("/sysroot", "/", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110004,gid=110004,inode64"),
+ r("/", "/proc", "rw,nosuid,nodev,noexec,relatime", "proc", "proc", "rw"),
+ r("/", "/.hakurei", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=4k,mode=755,uid=110004,gid=110004,inode64"),
+ r("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", "rw,mode=755,uid=110004,gid=110004,inode64"),
+ r("/null", "/dev/null", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/zero", "/dev/zero", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/full", "/dev/full", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/random", "/dev/random", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/urandom", "/dev/urandom", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/tty", "/dev/tty", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/", "/dev/pts", "rw,nosuid,noexec,relatime", "devpts", "devpts", "rw,mode=620,ptmxmode=666"),
+ r("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
+ r("/", "/dev/shm", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110004,gid=110004,inode64"),
+ r("/", "/run/user", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=16384k,mode=755,uid=110004,gid=110004,inode64"),
+ r("/tmp/hakurei.0/runtime/5", "/run/user/65534", "rw,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/tmp/hakurei.0/tmpdir/5", "/tmp", "rw,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/etc/passwd", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110004,gid=110004,inode64"),
+ r(ignore, "/etc/group", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110004,gid=110004,inode64"),
+ r(ignore, "/run/user/65534/wayland-0", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/bus", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/usr/lib", "/lib", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/opt/test-helper/bin/tester", "/.hakurei/test-helper", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/pulse/native", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ },
+
+ Seccomp: true,
+
+ TrySocket: "/tmp/.X11-unix/X0",
+ ErrnoAbstract: syscall.EPERM,
+ ErrnoPathname: syscall.ENOENT,
+}.register("pdlike")
diff --git a/test/sandbox/testdata/simple.go b/test/sandbox/testdata/simple.go
new file mode 100644
index 00000000..c410e626
--- /dev/null
+++ b/test/sandbox/testdata/simple.go
@@ -0,0 +1,140 @@
+//go:build testsuite || tester
+
+package testdata
+
+import (
+ "os"
+ "syscall"
+
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/internal/testsuite"
+)
+
+var _ = TestCase{
+ Hakurei: hst.Config{
+ ID: "app.hakurei.sample.simple",
+ Enablements: new(hst.EWayland | hst.EPipeWire | hst.EDBus),
+ Identity: 1,
+
+ Container: &hst.ContainerConfig{
+ Hostname: "hakurei-sample-simple",
+ Env: map[string]string{"HAKUREI_SAMPLE": "1"},
+
+ Filesystem: []hst.FilesystemConfigJSON{
+ fcLinker,
+ fcLib,
+ fcTestHelper,
+ },
+
+ Username: "u0_a1",
+ Shell: fhs.AbsUsrBin.Append("bash"),
+ Home: hst.AbsPrivateTmp,
+ Path: absTestHelper,
+ Args: []string{"tester", "simple"},
+ },
+ },
+
+ // 0, PresetStrict
+ Sum: sumSimple,
+
+ Env: []string{
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus",
+ "HAKUREI_SAMPLE=1",
+ "HOME=/.hakurei",
+ "SHELL=/usr/bin/bash",
+ "TERM=xterm",
+ "USER=u0_a1",
+ "WAYLAND_DISPLAY=wayland-0",
+ "XDG_RUNTIME_DIR=/run/user/65534",
+ "XDG_SESSION_CLASS=user",
+ "XDG_SESSION_TYPE=wayland",
+ "PULSE_SERVER=unix:/run/user/65534/pulse/native",
+ },
+
+ FS: &testsuite.FS{Dir: dir{
+ ".hakurei": {Mode: os.ModeDir | 0755, Dir: dir{
+ "test-helper": {Mode: 0755},
+ }},
+
+ "dev": {Mode: os.ModeDir | 0755, Dir: dir{
+ "core": {Mode: os.ModeSymlink | 0777},
+ "fd": {Mode: os.ModeSymlink | 0777},
+ "full": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "mqueue": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+ "null": {Mode: os.ModeDevice | os.ModeCharDevice | 0666, Data: new("")},
+ "ptmx": {Mode: os.ModeSymlink | 0777},
+ "pts": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ptmx": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ }},
+ "random": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "shm": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+ "stderr": {Mode: os.ModeSymlink | 0777},
+ "stdin": {Mode: os.ModeSymlink | 0777},
+ "stdout": {Mode: os.ModeSymlink | 0777},
+ "tty": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "urandom": {Mode: os.ModeDevice | os.ModeCharDevice | 0444},
+ "zero": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ }},
+
+ "etc": {Mode: os.ModeDir | 0755, Dir: dir{
+ "passwd": {Mode: 0600,
+ Data: new("u0_a1:x:65534:65534:Hakurei:/.hakurei:/usr/bin/bash\n")},
+ "group": {Mode: 0600,
+ Data: new("hakurei:x:65534:\n")},
+ }},
+
+ "lib64": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ld-linux-x86-64.so.2": {Mode: os.ModeSymlink | 0777},
+ }},
+
+ "run": {Mode: os.ModeDir | 0755, Dir: dir{
+ "user": {Mode: os.ModeDir | 0755, Dir: dir{
+ "65534": {Mode: os.ModeDir | 0700, Dir: dir{
+ "bus": {Mode: os.ModeSocket | 0775},
+ "wayland-0": {Mode: os.ModeSocket | 070},
+ "pulse": {Mode: os.ModeDir | 0700, Dir: dir{
+ "native": {Mode: os.ModeSocket | 0777},
+ }},
+ }},
+ }},
+ }},
+
+ "tmp": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+
+ "lib": {Mode: os.ModeDir | 0755},
+ "proc": {Mode: os.ModeDir | 0555},
+ }},
+
+ Mount: []*mountinfo.Entry{
+ r("/sysroot", "/", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110000,gid=110000,inode64"),
+ r("/", "/proc", "rw,nosuid,nodev,noexec,relatime", "proc", "proc", "rw"),
+ r("/", "/.hakurei", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=4k,mode=755,uid=110000,gid=110000,inode64"),
+ r("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", "rw,mode=755,uid=110000,gid=110000,inode64"),
+ r("/null", "/dev/null", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/zero", "/dev/zero", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/full", "/dev/full", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/random", "/dev/random", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/urandom", "/dev/urandom", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/tty", "/dev/tty", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/", "/dev/pts", "rw,nosuid,noexec,relatime", "devpts", "devpts", "rw,mode=620,ptmxmode=666"),
+ r("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
+ r("/", "/dev/shm", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110000,gid=110000,inode64"),
+ r("/", "/run/user", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=16384k,mode=755,uid=110000,gid=110000,inode64"),
+ r("/", "/tmp", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110000,gid=110000,inode64"),
+ r(ignore, "/etc/passwd", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110000,gid=110000,inode64"),
+ r(ignore, "/etc/group", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110000,gid=110000,inode64"),
+ r(ignore, "/run/user/65534/wayland-0", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/bus", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/usr/lib", "/lib", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/opt/test-helper/bin/tester", "/.hakurei/test-helper", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/pulse/native", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ },
+
+ Seccomp: true,
+
+ TrySocket: "/tmp/.X11-unix/X0",
+ ErrnoAbstract: syscall.ECONNREFUSED,
+ ErrnoPathname: syscall.ENOENT,
+}.register("simple")
diff --git a/test/sandbox/testdata/sum.go b/test/sandbox/testdata/sum.go
new file mode 100644
index 00000000..e4e8643a
--- /dev/null
+++ b/test/sandbox/testdata/sum.go
@@ -0,0 +1,22 @@
+//go:build testsuite || tester
+
+package testdata
+
+import (
+ "crypto/sha512"
+ "encoding/base64"
+ "strconv"
+)
+
+// sum decodes s as [base64.StdEncoding] and panics if it is invalid or
+// unexpectedly sized.
+func sum(s string) [sha512.Size]byte {
+ p, err := base64.StdEncoding.DecodeString(s)
+ if err != nil {
+ panic(err)
+ }
+ if len(p) != sha512.Size {
+ panic("unexpected checksum sized " + strconv.Itoa(len(p)))
+ }
+ return ([sha512.Size]byte)(p)
+}
diff --git a/test/sandbox/testdata/sum_amd64.go b/test/sandbox/testdata/sum_amd64.go
new file mode 100644
index 00000000..bd751105
--- /dev/null
+++ b/test/sandbox/testdata/sum_amd64.go
@@ -0,0 +1,9 @@
+//go:build testsuite || tester
+
+package testdata
+
+var (
+ SumPD = sum("xpiwgf+Vev4XptlDdFN9N/KmP2+d112nVGVCQHqeMkduvaMxK6d4XX9hhUK8+vJ8on3MLd26hSBp0ovP6MrTmg==")
+ sumSimple = sum("6IApjfK9Z1HQBA/CG8DtTAD5XcDXulBsJE2LjPaGbbqO9KMylvKHtmzMwdeOlwJll/hMx97BVz4UiWD701zXNQ==")
+ sumTTY = sum("C3YAdHbByeJdv2dMKf32CaFlanAGPkkydlThtTYK09oG4aPjK/gOlhxVFq2D1Lnn6b3odqk3l+J2J9JVXCWFiw==")
+)
diff --git a/test/sandbox/testdata/sum_arm64.go b/test/sandbox/testdata/sum_arm64.go
new file mode 100644
index 00000000..1691828f
--- /dev/null
+++ b/test/sandbox/testdata/sum_arm64.go
@@ -0,0 +1,9 @@
+//go:build testsuite || tester
+
+package testdata
+
+var (
+ SumPD = sum("QzzpuREoLW3MgCkxn7ebgWtg1aeV7I/JQ0TdAnYU1o8CMWapG7iB+q7u3Sbj2JR04UHlppqX6TuJhMqPFJmZgA==")
+ sumSimple = sum("eTGFOKPchRMUtr2W8Q1YYayyqn4Ty43gYZ0PanZwnWfwHvP9Z+GVhisC+XEeW3abxNHrT8DfxBpyPInJaKkylw==")
+ sumTTY = sum("zx9NyHQ2uo7JXSaLZjpjl7sLSlrGTYVX5sxSnYsPb2Xa06krYu0p2F7unG3eEmd1ek0PhgMuikXKG86t+jTPXg==")
+)
diff --git a/test/sandbox/testdata/testdata.go b/test/sandbox/testdata/testdata.go
new file mode 100644
index 00000000..3418d8ae
--- /dev/null
+++ b/test/sandbox/testdata/testdata.go
@@ -0,0 +1,125 @@
+//go:build testsuite || tester
+
+// Package testdata holds sandbox inspection test cases.
+package testdata
+
+import (
+ "crypto/sha512"
+ "iter"
+ "log"
+ "strconv"
+ "syscall"
+
+ "hakurei.app/check"
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/internal/testsuite"
+)
+
+// A TestCase represents a named test case that may be requested by the caller.
+type TestCase struct {
+ // Configuration of the inspected container.
+ Hakurei hst.Config
+ // Checksum of expected seccomp filter program.
+ Sum [sha512.Size]byte
+
+ // Expected environment. Skipped if nil.
+ Env []string `json:"env,omitempty"`
+ // Expected root filesystem. Skipped if nil.
+ FS *testsuite.FS `json:"fs,omitempty"`
+ // Expected mountinfo records. Skipped if nil.
+ Mount []*mountinfo.Entry `json:"mount,omitempty"`
+ // Whether to run seccomp checks.
+ Seccomp bool `json:"seccomp,omitempty"`
+
+ // Name of pathname and abstract sockets to attempt.
+ TrySocket string `json:"try_socket,omitempty"`
+ // Errno to expect attempting to reach the abstract socket.
+ ErrnoAbstract syscall.Errno `json:"errno_abstract,omitempty"`
+ // Errno to expect attempting to reach the pathname socket.
+ ErrnoPathname syscall.Errno `json:"errno_pathname,omitempty"`
+}
+
+// testCases hold all named test cases.
+var testCases map[string]TestCase
+
+// fc returns c wrapped in its JSON adapter.
+func fc(c hst.FilesystemConfig) hst.FilesystemConfigJSON {
+ return hst.FilesystemConfigJSON{
+ FilesystemConfig: c,
+ }
+}
+
+// ignore is the magic string for a mountinfo field to be ignored.
+const ignore = "//ignore"
+
+type dir = map[string]*testsuite.FS
+
+// r returns the address of a [mountinfo.Entry].
+func r(
+ root, target, vfsOptstr string,
+ fsType, source, fsOptstr string,
+) *mountinfo.Entry {
+ return &mountinfo.Entry{
+ ID: -1,
+ Parent: -1,
+ Root: root,
+ Target: target,
+ VfsOptstr: vfsOptstr,
+ FsType: fsType,
+ Source: source,
+ FsOptstr: fsOptstr,
+ }
+}
+
+var (
+ // fcLinker is the dynamic linker symlink.
+ fcLinker = fc(&hst.FSLink{
+ Target: fhs.AbsRoot.Append("lib64", "ld-linux-x86-64.so.2"),
+ Linkname: "../lib/x86_64-linux-gnu/ld-linux-x86-64.so.2",
+ })
+ // fcLib is the dynamic library bind mount.
+ fcLib = fc(&hst.FSBind{Source: fhs.AbsRoot.Append("lib")})
+
+ // absTestHelper is the absolute pathname of the test helper program.
+ absTestHelper = hst.AbsPrivateTmp.Append("test-helper")
+ // fcTestHelper is the test helper bind mount.
+ fcTestHelper = fc(&hst.FSBind{
+ Target: absTestHelper,
+ Source: check.MustAbs("/opt/test-helper/bin/tester"),
+ })
+)
+
+// register adds a test case to testCases.
+func (c TestCase) register(name string) (_ struct{}) {
+ if testCases == nil {
+ testCases = make(map[string]TestCase)
+ }
+
+ if _, ok := testCases[name]; ok {
+ panic("attempting to register " + strconv.Quote(name) + " twice")
+ }
+ testCases[name] = c
+ return
+}
+
+// Get returns the named test case, or terminates the program if name is invalid.
+func Get(name string) TestCase {
+ tc, ok := testCases[name]
+ if !ok {
+ log.Fatalf("invalid test case %q", name)
+ }
+ return tc
+}
+
+// All returns an iterator over all named test cases.
+func All() iter.Seq2[string, TestCase] {
+ return func(yield func(string, TestCase) bool) {
+ for name, tc := range testCases {
+ if !yield(name, tc) {
+ return
+ }
+ }
+ }
+}
diff --git a/test/sandbox/testdata/tty.go b/test/sandbox/testdata/tty.go
new file mode 100644
index 00000000..4788f484
--- /dev/null
+++ b/test/sandbox/testdata/tty.go
@@ -0,0 +1,145 @@
+//go:build testsuite || tester
+
+package testdata
+
+import (
+ "os"
+
+ "hakurei.app/fhs"
+ "hakurei.app/hst"
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/internal/testsuite"
+)
+
+var _ = TestCase{
+ Hakurei: hst.Config{
+ ID: "app.hakurei.sample.tty",
+ Enablements: new(hst.EWayland | hst.EPipeWire | hst.EDBus | hst.EX11),
+ Identity: 2,
+
+ Container: &hst.ContainerConfig{
+ Hostname: "hakurei-sample-tty",
+
+ Filesystem: []hst.FilesystemConfigJSON{
+ fcLinker,
+ fcLib,
+ fcTestHelper,
+ },
+
+ Username: "u0_a2",
+ Shell: fhs.AbsUsrBin.Append("bash"),
+ Home: hst.AbsPrivateTmp,
+ Path: absTestHelper,
+ Args: []string{"tester", "tty"},
+
+ Flags: hst.FHostNet | hst.FHostAbstract |
+ hst.FTty | hst.FShareRuntime,
+ },
+ },
+
+ // 0, PresetExt | PresetDenyNS | PresetDenyDevel
+ Sum: sumTTY,
+
+ Env: []string{
+ "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus",
+ "DISPLAY=:0",
+ "HOME=/.hakurei",
+ "SHELL=/usr/bin/bash",
+ "TERM=xterm",
+ "USER=u0_a2",
+ "WAYLAND_DISPLAY=wayland-0",
+ "XDG_RUNTIME_DIR=/run/user/65534",
+ "XDG_SESSION_CLASS=user",
+ "XDG_SESSION_TYPE=wayland",
+ "PULSE_SERVER=unix:/run/user/65534/pulse/native",
+ },
+
+ FS: &testsuite.FS{Dir: dir{
+ ".hakurei": {Mode: os.ModeDir | 0755, Dir: dir{
+ "test-helper": {Mode: 0755},
+ }},
+
+ "dev": {Mode: os.ModeDir | 0755, Dir: dir{
+ "core": {Mode: os.ModeSymlink | 0777},
+ "fd": {Mode: os.ModeSymlink | 0777},
+ "full": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "mqueue": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+ "null": {Mode: os.ModeDevice | os.ModeCharDevice | 0666, Data: new("")},
+ "ptmx": {Mode: os.ModeSymlink | 0777},
+ "pts": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ptmx": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ }},
+ "random": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "shm": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{}},
+ "stderr": {Mode: os.ModeSymlink | 0777},
+ "stdin": {Mode: os.ModeSymlink | 0777},
+ "stdout": {Mode: os.ModeSymlink | 0777},
+ "tty": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ "urandom": {Mode: os.ModeDevice | os.ModeCharDevice | 0444},
+ "zero": {Mode: os.ModeDevice | os.ModeCharDevice | 0666},
+ }},
+
+ "etc": {Mode: os.ModeDir | 0755, Dir: dir{
+ "passwd": {Mode: 0600,
+ Data: new("u0_a2:x:65534:65534:Hakurei:/.hakurei:/usr/bin/bash\n")},
+ "group": {Mode: 0600,
+ Data: new("hakurei:x:65534:\n")},
+ }},
+
+ "lib64": {Mode: os.ModeDir | 0755, Dir: dir{
+ "ld-linux-x86-64.so.2": {Mode: os.ModeSymlink | 0777},
+ }},
+
+ "run": {Mode: os.ModeDir | 0755, Dir: dir{
+ "user": {Mode: os.ModeDir | 0755, Dir: dir{
+ "65534": {Mode: os.ModeDir | 0770, Dir: dir{
+ "bus": {Mode: os.ModeSocket | 0775},
+ "wayland-0": {Mode: os.ModeSocket | 070},
+ "pulse": {Mode: os.ModeDir | 0700, Dir: dir{
+ "native": {Mode: os.ModeSocket | 0777},
+ }},
+ }},
+ }},
+ }},
+
+ "tmp": {Mode: os.ModeDir | os.ModeSticky | 0777, Dir: dir{
+ ".X11-unix": {Mode: os.ModeDir | 0755, Dir: dir{
+ "X0": {Mode: os.ModeSocket | 0775},
+ }},
+ }},
+
+ "lib": {Mode: os.ModeDir | 0755},
+ "proc": {Mode: os.ModeDir | 0555},
+ }},
+
+ Mount: []*mountinfo.Entry{
+ r("/sysroot", "/", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110001,gid=110001,inode64"),
+ r("/", "/proc", "rw,nosuid,nodev,noexec,relatime", "proc", "proc", "rw"),
+ r("/", "/.hakurei", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=4k,mode=755,uid=110001,gid=110001,inode64"),
+ r("/", "/dev", "ro,nosuid,nodev,relatime", "tmpfs", "devtmpfs", "rw,mode=755,uid=110001,gid=110001,inode64"),
+ r("/null", "/dev/null", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/zero", "/dev/zero", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/full", "/dev/full", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/random", "/dev/random", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/urandom", "/dev/urandom", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/tty", "/dev/tty", "rw,nosuid,noexec,relatime", "devtmpfs", "devtmpfs", ignore),
+ r("/", "/dev/pts", "rw,nosuid,noexec,relatime", "devpts", "devpts", "rw,mode=620,ptmxmode=666"),
+ r("/", "/dev/mqueue", "rw,nosuid,nodev,noexec,relatime", "mqueue", "mqueue", "rw"),
+ r("/", "/dev/shm", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110001,gid=110001,inode64"),
+ r("/", "/run/user", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,size=16384k,mode=755,uid=110001,gid=110001,inode64"),
+ r("/tmp/hakurei.0/runtime/2", "/run/user/65534", "rw,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/", "/tmp", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", "rw,uid=110001,gid=110001,inode64"),
+ r(ignore, "/etc/passwd", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110001,gid=110001,inode64"),
+ r(ignore, "/etc/group", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", "rw,uid=110001,gid=110001,inode64"),
+ r(ignore, "/run/user/65534/wayland-0", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/tmp/.X11-unix", "/tmp/.X11-unix", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/bus", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/usr/lib", "/lib", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r("/opt/test-helper/bin/tester", "/.hakurei/test-helper", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ r(ignore, "/run/user/65534/pulse/native", "ro,nosuid,nodev,relatime", "overlay", "overlay", ignore),
+ },
+
+ Seccomp: true,
+
+ TrySocket: "/tmp/.X11-unix/X0",
+}.register("tty")
diff --git a/test/sandbox/tester/main.go b/test/sandbox/tester/main.go
new file mode 100644
index 00000000..0782a5e0
--- /dev/null
+++ b/test/sandbox/tester/main.go
@@ -0,0 +1,224 @@
+//go:build tester
+
+// The sandbox tester runs within a cmd/hakurei container and validates its
+// state. Since the test environment is relatively predictable, the tester can
+// make various assumptions about the host.
+package main
+
+import (
+ "errors"
+ "log"
+ "net"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "syscall"
+
+ "hakurei.app/test/internal/mountinfo"
+ "hakurei.app/test/sandbox/testdata"
+)
+
+//#include <sys/quota.h>
+import "C"
+
+// mustAbs returns s, or terminates the program if s is not absolute.
+func mustAbs(s string) string {
+ if !filepath.IsAbs(s) {
+ log.Fatalf("%q is not absolute", s)
+ }
+ return s
+}
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("tester: ")
+
+ if len(os.Args) != 2 {
+ log.Fatal("tester requires 1 argument")
+ }
+ want := testdata.Get(os.Args[1])
+ log.SetPrefix("tester: " + os.Args[1] + " ")
+
+ checkWritableDirPaths := []string{
+ "/dev/shm",
+ "/tmp",
+ os.Getenv("XDG_RUNTIME_DIR"),
+ }
+ for _, a := range checkWritableDirPaths {
+ pathname := filepath.Join(mustAbs(a), ".hakurei-check")
+ if err := os.WriteFile(pathname, make([]byte, 1<<8), 0600); err != nil {
+ log.Fatalf("[FAIL] %s", err)
+ } else if err = os.Remove(pathname); err != nil {
+ log.Fatalf("[FAIL] %s", err)
+ } else {
+ log.Printf("[ OK ] %s is writable", a)
+ }
+ }
+
+ if want.Env != nil {
+ var (
+ fail bool
+ i int
+ got string
+ )
+ for i, got = range os.Environ() {
+ if i == len(want.Env) {
+ log.Fatalf("got more than %d environment variables", len(want.Env))
+ }
+ if got != want.Env[i] {
+ fail = true
+ log.Printf("[FAIL] %s", got)
+ } else {
+ log.Printf("[ OK ] %s", got)
+ }
+ }
+
+ i++
+ if i != len(want.Env) {
+ log.Fatalf("got %d environment variables, want %d", i, len(want.Env))
+ }
+
+ if fail {
+ log.Fatalf("[FAIL] some environment variables did not match")
+ }
+ } else {
+ log.Printf("[SKIP] skipping environ check")
+ }
+
+ if want.FS != nil {
+ if err := want.FS.Compare(log.Printf, ".", os.DirFS("/")); err != nil {
+ log.Fatalf("%v", err)
+ }
+ } else {
+ log.Printf("[SKIP] skipping fs check")
+ }
+
+ if want.Mount != nil {
+ var fail bool
+
+ m, err := mountinfo.Open("")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ i := 0
+ var ent mountinfo.Entry
+ for m.Next() {
+ m.Copy(&ent)
+
+ if i == len(want.Mount) {
+ log.Fatalf("got more than %d entries", i)
+ }
+ if !ent.EqualWithIgnore(want.Mount[i], "//ignore") {
+ fail = true
+ log.Printf("[FAIL] %s", &ent)
+ } else {
+ log.Printf("[ OK ] %s", &ent)
+ }
+
+ i++
+ }
+ if err = m.Err(); err != nil {
+ log.Fatalf("%v", err)
+ }
+
+ if i != len(want.Mount) {
+ log.Fatalf("got %d entries, want %d", i, len(want.Mount))
+ }
+
+ if fail {
+ log.Fatalf("[FAIL] some mount points did not match")
+ }
+ } else {
+ log.Printf("[SKIP] skipping mounts check")
+ }
+
+ if want.Seccomp {
+ const NULL = 0
+
+ for _, tc := range []struct {
+ name string
+ errno syscall.Errno
+
+ trap, a1, a2, a3, a4, a5, a6 uintptr
+ }{
+ {"syslog", syscall.EPERM, syscall.SYS_SYSLOG, 0, NULL, NULL, NULL, NULL, NULL},
+ {"acct", syscall.EPERM, syscall.SYS_ACCT, 0, NULL, NULL, NULL, NULL, NULL},
+ {"quotactl", syscall.EPERM, syscall.SYS_QUOTACTL, C.Q_GETQUOTA, NULL, uintptr(os.Getuid()), NULL, NULL, NULL},
+ {"add_key", syscall.EPERM, syscall.SYS_ADD_KEY, NULL, NULL, NULL, NULL, NULL, NULL},
+ {"keyctl", syscall.EPERM, syscall.SYS_KEYCTL, NULL, NULL, NULL, NULL, NULL, NULL},
+ {"request_key", syscall.EPERM, syscall.SYS_REQUEST_KEY, NULL, NULL, NULL, NULL, NULL, NULL},
+ {"move_pages", syscall.EPERM, syscall.SYS_MOVE_PAGES, uintptr(os.Getpid()), NULL, NULL, NULL, NULL, NULL},
+ {"mbind", syscall.EPERM, syscall.SYS_MBIND, NULL, NULL, NULL, NULL, NULL, NULL},
+ {"get_mempolicy", syscall.EPERM, syscall.SYS_GET_MEMPOLICY, NULL, NULL, NULL, NULL, NULL, NULL},
+ {"set_mempolicy", syscall.EPERM, syscall.SYS_SET_MEMPOLICY, NULL, NULL, NULL, NULL, NULL, NULL},
+ {"migrate_pages", syscall.EPERM, syscall.SYS_MIGRATE_PAGES, NULL, NULL, NULL, NULL, NULL, NULL},
+ } {
+ if _, _, errno := syscall.Syscall6(tc.trap, tc.a1, tc.a2, tc.a3, tc.a4, tc.a5, tc.a6); errno != tc.errno {
+ log.Fatalf("[FAIL] %s: %v, want %v", tc.name, errno, tc.errno)
+ }
+ log.Printf("[ OK ] %s: %v", tc.name, tc.errno)
+ }
+ } else {
+ log.Printf("[SKIP] skipping seccomp check")
+ }
+
+ if want.TrySocket != "" {
+ retry:
+ abstractConn, abstractErr := net.Dial("unix", "@"+want.TrySocket)
+ pathnameConn, pathnameErr := net.Dial("unix", want.TrySocket)
+ ok := true
+
+ if abstractErr == nil {
+ if err := abstractConn.Close(); err != nil {
+ ok = false
+ log.Printf("Close: %v", err)
+ }
+ }
+ if pathnameErr == nil {
+ if err := pathnameConn.Close(); err != nil {
+ ok = false
+ log.Printf("Close: %v", err)
+ }
+ }
+
+ if errors.Is(
+ abstractErr,
+ syscall.EAGAIN,
+ ) || errors.Is(
+ pathnameErr,
+ syscall.EAGAIN,
+ ) {
+ goto retry
+ }
+
+ abstractWantErr := error(want.ErrnoAbstract)
+ pathnameWantErr := error(want.ErrnoPathname)
+ if want.ErrnoAbstract == 0 {
+ abstractWantErr = nil
+ }
+ if want.ErrnoPathname == 0 {
+ pathnameWantErr = nil
+ }
+
+ if !errors.Is(abstractErr, abstractWantErr) {
+ ok = false
+ log.Printf("abstractErr: %v, want %v", abstractErr, abstractWantErr)
+ }
+ if !errors.Is(pathnameErr, pathnameWantErr) {
+ ok = false
+ log.Printf("pathnameErr: %v, want %v", pathnameErr, pathnameWantErr)
+ }
+
+ if !ok {
+ os.Exit(1)
+ }
+ }
+
+ s := make(chan os.Signal, 1)
+ signal.Notify(s, syscall.SIGTERM)
+ if _, err := os.Stdout.Write(make([]byte, 8)); err != nil {
+ log.Fatalf("cannot notify testsuite: %v", err)
+ }
+ <-s
+}
diff --git a/test/sandbox/tool/main.go b/test/sandbox/tool/main.go
deleted file mode 100644
index 889142d4..00000000
--- a/test/sandbox/tool/main.go
+++ /dev/null
@@ -1,106 +0,0 @@
-//go:build testtool
-
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "os"
- "os/signal"
- "strconv"
- "strings"
- "syscall"
-
- "hakurei.app/test/internal/sandbox"
-)
-
-var (
- flagMarkerPath string
- flagTestCase string
- flagBpfHash string
-)
-
-func init() {
- flag.StringVar(&flagMarkerPath, "p", "/tmp/sandbox-ok", "Pathname of completion marker")
- flag.StringVar(&flagTestCase, "t", "", "Nix store path to test case file")
- flag.StringVar(&flagBpfHash, "s", "", "String representation of expected bpf sha512 hash")
-}
-
-func main() {
- log.SetFlags(0)
- log.SetPrefix("test: ")
- flag.Parse()
-
- args := flag.Args()
- if len(args) < 1 {
- s := make(chan os.Signal, 1)
- signal.Notify(s, syscall.SIGINT)
- go func() { <-s; log.Println("exiting on signal (likely from verifier)"); os.Exit(0) }()
-
- (&sandbox.T{FS: os.DirFS("/")}).MustCheckFile(flagTestCase)
- if _, err := os.Create(flagMarkerPath); err != nil {
- log.Fatalf("cannot create success marker: %v", err)
- }
- log.Printf("blocking for seccomp check (%s)", flagMarkerPath)
- select {}
- return
- }
-
- switch args[0] {
- case "filter":
- if len(args) != 2 {
- log.Fatal("invalid argument")
- }
-
- if pid, err := strconv.Atoi(strings.TrimSpace(args[1])); err != nil {
- log.Fatalf("%s", err)
- } else if pid < 1 {
- log.Fatalf("%d out of range", pid)
- } else {
- sandbox.MustCheckFilter(pid, flagBpfHash)
- if err = syscall.Kill(pid, syscall.SIGINT); err != nil {
- log.Fatalf("cannot signal check process: %v", err)
- }
- }
-
- case "hash": // this eases the pain of passing the hash to python
- fmt.Print(flagBpfHash)
-
- case "fd":
- if len(args) != 2 {
- log.Fatal("invalid argument")
- }
- prefix := fmt.Sprintf("/proc/%s/fd/", args[1])
-
- var fail bool
- if entries, err := os.ReadDir(prefix); err != nil {
- log.Fatal(err.Error())
- } else {
- for _, ent := range entries {
- var fd int
- if fd, err = strconv.Atoi(ent.Name()); err != nil {
- log.Fatal(err.Error())
- }
-
- // skip standard streams
- if fd <= 2 {
- continue
- }
- fail = true
-
- var d string
- if d, err = os.Readlink(prefix + ent.Name()); err != nil {
- log.Fatal(err.Error())
- }
- log.Printf("[FAIL] extra fd %d -> %s", fd, d)
- }
- }
- if fail {
- log.Fatal("[FAIL] file descriptors leaked")
- }
-
- default:
- log.Fatal("invalid argument")
- }
-}
diff --git a/test/sandbox/tool/package.nix b/test/sandbox/tool/package.nix
deleted file mode 100644
index bd57b432..00000000
--- a/test/sandbox/tool/package.nix
+++ /dev/null
@@ -1,32 +0,0 @@
-{
- lib,
- buildGoModule,
- pkg-config,
- util-linux,
-
- version,
-}:
-buildGoModule rec {
- pname = "check-sandbox";
- inherit version;
-
- src = builtins.path {
- name = "${pname}-src";
- path = lib.cleanSource ../../.;
- filter = path: type: (type == "directory") || (type == "regular" && lib.hasSuffix ".go" path);
- };
- vendorHash = null;
-
- tags = [ "testtool" "tester" ];
-
- buildInputs = [ util-linux ];
- nativeBuildInputs = [ pkg-config ];
-
- preBuild = ''
- go mod init hakurei.app/test >& /dev/null
- '';
-
- postInstall = ''
- mv $out/bin/tool $out/bin/hakurei-test
- '';
-}