From ca247b80378b7248ed4d1eda8a97e2a1d659ec7b Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 14 Sep 2025 01:35:17 +0900 Subject: [PATCH] internal/app: mount /dev/shm early This avoids covering /dev/shm mounts from hst. Signed-off-by: Ophestra --- internal/app/app_nixos_linux_test.go | 2 +- internal/app/app_pd_linux_test.go | 4 ++-- internal/app/container.go | 6 +++--- test/sandbox/assert.go | 7 +++++++ test/sandbox/case/device.nix | 3 ++- test/sandbox/case/mapuid.nix | 4 ++-- test/sandbox/case/pd.nix | 4 ++-- test/sandbox/case/pdlike.nix | 4 ++-- test/sandbox/case/preset.nix | 4 ++-- test/sandbox/case/tty.nix | 4 ++-- test/test.py | 2 +- 11 files changed, 26 insertions(+), 18 deletions(-) diff --git a/internal/app/app_nixos_linux_test.go b/internal/app/app_nixos_linux_test.go index b6f5e44..f38c27b 100644 --- a/internal/app/app_nixos_linux_test.go +++ b/internal/app/app_nixos_linux_test.go @@ -135,6 +135,7 @@ var testCasesNixos = []sealTestCase{ Proc(m("/proc/")). Tmpfs(hst.AbsTmp, 4096, 0755). DevWritable(m("/dev/"), true). + Tmpfs(m("/dev/shm"), 0, 01777). Bind(m("/bin"), m("/bin"), 0). Bind(m("/usr/bin/"), m("/usr/bin/"), 0). Bind(m("/nix/store"), m("/nix/store"), 0). @@ -149,7 +150,6 @@ var testCasesNixos = []sealTestCase{ Etc(m("/etc/"), "8e2c76b066dabe574cf073bdb46eb5c1"). Bind(m("/var/lib/persist/module/hakurei/0/1"), m("/var/lib/persist/module/hakurei/0/1"), container.BindWritable|container.BindEnsure). Remount(m("/dev/"), syscall.MS_RDONLY). - Tmpfs(m("/dev/shm"), 0, 01777). Tmpfs(m("/run/user/"), 4096, 0755). Bind(m("/tmp/hakurei.1971/runtime/1"), m("/run/user/1971"), container.BindWritable). Bind(m("/tmp/hakurei.1971/tmpdir/1"), m("/tmp/"), container.BindWritable). diff --git a/internal/app/app_pd_linux_test.go b/internal/app/app_pd_linux_test.go index 7bc9473..4a6bb73 100644 --- a/internal/app/app_pd_linux_test.go +++ b/internal/app/app_pd_linux_test.go @@ -48,13 +48,13 @@ var testCasesPd = []sealTestCase{ Proc(m("/proc/")). Tmpfs(hst.AbsTmp, 4096, 0755). DevWritable(m("/dev/"), true). + Tmpfs(m("/dev/shm"), 0, 01777). Bind(m("/dev/kvm"), m("/dev/kvm"), container.BindWritable|container.BindDevice|container.BindOptional). Readonly(m("/var/run/nscd"), 0755). Etc(m("/etc/"), "4a450b6596d7bc15bd01780eb9a607ac"). Tmpfs(m("/run/user/1971"), 8192, 0755). Tmpfs(m("/run/dbus"), 8192, 0755). Remount(m("/dev/"), syscall.MS_RDONLY). - Tmpfs(m("/dev/shm"), 0, 01777). Tmpfs(m("/run/user/"), 4096, 0755). Bind(m("/tmp/hakurei.1971/runtime/0"), m("/run/user/65534"), container.BindWritable). Bind(m("/tmp/hakurei.1971/tmpdir/0"), m("/tmp/"), container.BindWritable). @@ -184,6 +184,7 @@ var testCasesPd = []sealTestCase{ Proc(m("/proc/")). Tmpfs(hst.AbsTmp, 4096, 0755). DevWritable(m("/dev/"), true). + Tmpfs(m("/dev/shm"), 0, 01777). Bind(m("/dev/dri"), m("/dev/dri"), container.BindWritable|container.BindDevice|container.BindOptional). Bind(m("/dev/kvm"), m("/dev/kvm"), container.BindWritable|container.BindDevice|container.BindOptional). Readonly(m("/var/run/nscd"), 0755). @@ -191,7 +192,6 @@ var testCasesPd = []sealTestCase{ Tmpfs(m("/run/user/1971"), 8192, 0755). Tmpfs(m("/run/dbus"), 8192, 0755). Remount(m("/dev/"), syscall.MS_RDONLY). - Tmpfs(m("/dev/shm"), 0, 01777). Tmpfs(m("/run/user/"), 4096, 0755). Bind(m("/tmp/hakurei.1971/runtime/9"), m("/run/user/65534"), container.BindWritable). Bind(m("/tmp/hakurei.1971/tmpdir/9"), m("/tmp/"), container.BindWritable). diff --git a/internal/app/container.go b/internal/app/container.go index 68ba55e..26bda26 100644 --- a/internal/app/container.go +++ b/internal/app/container.go @@ -98,6 +98,8 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid } else { params.Bind(container.AbsFHSDev, container.AbsFHSDev, container.BindWritable|container.BindDevice) } + // /dev is mounted readonly later on, this prevents /dev/shm from going readonly with it + params.Tmpfs(container.AbsFHSDev.Append("shm"), 0, 01777) /* retrieve paths and hide them if they're made available in the sandbox; @@ -230,9 +232,7 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid // no more ContainerConfig paths beyond this point if !s.Device { - params. - Remount(container.AbsFHSDev, syscall.MS_RDONLY). - Tmpfs(container.AbsFHSDev.Append("shm"), 0, 01777) + params.Remount(container.AbsFHSDev, syscall.MS_RDONLY) } return params, maps.Clone(s.Env), nil diff --git a/test/sandbox/assert.go b/test/sandbox/assert.go index 2c2c9f2..6dbb53b 100644 --- a/test/sandbox/assert.go +++ b/test/sandbox/assert.go @@ -53,6 +53,13 @@ func (t *T) MustCheckFile(wantFilePath string) { } func (t *T) MustCheck(want *TestCase) { + // check /dev/shm writable + if err := os.WriteFile("/dev/shm/.hakurei-check", make([]byte, 1<<8), 0600); err != nil { + fatalf("[FAIL] %s", err) + } else { + printf("[ OK ] /dev/shm is writable") + } + if want.Env != nil { var ( fail bool diff --git a/test/sandbox/case/device.nix b/test/sandbox/case/device.nix index d0f6289..7fc56da 100644 --- a/test/sandbox/case/device.nix +++ b/test/sandbox/case/device.nix @@ -213,9 +213,10 @@ in (ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000004,gid=1000004") (ent "/" "/dev" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) (ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666") - (ent "/" "/dev/shm" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore) + (ent "/" "/dev/shm" "rw,nosuid,nodev" "tmpfs" "tmpfs" "rw") (ent "/" ignore ignore ignore ignore ignore) # order not deterministic (ent "/" ignore ignore ignore ignore ignore) + (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000004,gid=1000004") (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on") diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix index c6dc848..fc46466 100644 --- a/test/sandbox/case/mapuid.nix +++ b/test/sandbox/case/mapuid.nix @@ -73,7 +73,7 @@ in ptmx = fs "80001ff" null null; pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; random = fs "42001b6" null null; - shm = fs "801001ff" { } null; + shm = fs "801001ff" { ".hakurei-check" = fs "180" null null; } null; stderr = fs "80001ff" null null; stdin = fs "80001ff" null null; stdout = fs "80001ff" null null; @@ -243,6 +243,7 @@ in (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=1000003,gid=1000003") (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on") @@ -257,7 +258,6 @@ in (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/host/nix/.ro-store:/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/disk/by-label/nixos" "rw") (ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") - (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000003,gid=1000003") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000003,gid=1000003") (ent "/tmp/hakurei.0/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/tmp/hakurei.0/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix index 0222892..ea07922 100644 --- a/test/sandbox/case/pd.nix +++ b/test/sandbox/case/pd.nix @@ -36,7 +36,7 @@ ptmx = fs "80001ff" null null; pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; random = fs "42001b6" null null; - shm = fs "801001ff" { } null; + shm = fs "801001ff" { ".hakurei-check" = fs "180" null null; } null; stderr = fs "80001ff" null null; stdin = fs "80001ff" null null; stdout = fs "80001ff" null null; @@ -180,12 +180,12 @@ (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=1000000,gid=1000000") (ent "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) (ent "/" "/run/nscd" "ro,nosuid,nodev,relatime" "tmpfs" "readonly" "ro,mode=755,uid=1000000,gid=1000000") (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000") (ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000") - (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000000,gid=1000000") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000000,gid=1000000") (ent "/tmp/hakurei.0/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/tmp/hakurei.0/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") diff --git a/test/sandbox/case/pdlike.nix b/test/sandbox/case/pdlike.nix index 3b22809..1d8ac0e 100644 --- a/test/sandbox/case/pdlike.nix +++ b/test/sandbox/case/pdlike.nix @@ -71,7 +71,7 @@ in ptmx = fs "80001ff" null null; pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; random = fs "42001b6" null null; - shm = fs "801001ff" { } null; + shm = fs "801001ff" { ".hakurei-check" = fs "180" null null; } null; stderr = fs "80001ff" null null; stdin = fs "80001ff" null null; stdout = fs "80001ff" null null; @@ -241,6 +241,7 @@ in (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=1000005,gid=1000005") (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on") @@ -252,7 +253,6 @@ in (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") - (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000005,gid=1000005") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000005,gid=1000005") (ent "/tmp/hakurei.0/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/tmp/hakurei.0/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") diff --git a/test/sandbox/case/preset.nix b/test/sandbox/case/preset.nix index 32c0d61..61d0bbc 100644 --- a/test/sandbox/case/preset.nix +++ b/test/sandbox/case/preset.nix @@ -70,7 +70,7 @@ in ptmx = fs "80001ff" null null; pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; random = fs "42001b6" null null; - shm = fs "801001ff" { } null; + shm = fs "801001ff" { ".hakurei-check" = fs "180" null null; } null; stderr = fs "80001ff" null null; stdin = fs "80001ff" null null; stdout = fs "80001ff" null null; @@ -239,6 +239,7 @@ in (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=1000001,gid=1000001") (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on") @@ -250,7 +251,6 @@ in (ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore) (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") - (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000001,gid=1000001") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000001,gid=1000001") (ent "/tmp/hakurei.0/runtime/1" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/tmp/hakurei.0/tmpdir/1" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") diff --git a/test/sandbox/case/tty.nix b/test/sandbox/case/tty.nix index feb4833..197cc2e 100644 --- a/test/sandbox/case/tty.nix +++ b/test/sandbox/case/tty.nix @@ -75,7 +75,7 @@ in ptmx = fs "80001ff" null null; pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null; random = fs "42001b6" null null; - shm = fs "801001ff" { } null; + shm = fs "801001ff" { ".hakurei-check" = fs "180" null null; } null; stderr = fs "80001ff" null null; stdin = fs "80001ff" null null; stdout = fs "80001ff" null null; @@ -248,6 +248,7 @@ in (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=1000002,gid=1000002") (ent "/bin" "/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/usr/bin" "/usr/bin" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on") @@ -262,7 +263,6 @@ in (ent "/" "/.hakurei/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/host/nix/.ro-store:/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/disk/by-label/nixos" "rw") (ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") - (ent "/" "/dev/shm" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,uid=1000002,gid=1000002") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000002,gid=1000002") (ent "/tmp/hakurei.0/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/tmp/hakurei.0/tmpdir/2" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") diff --git a/test/test.py b/test/test.py index 4240b8f..4d31cee 100644 --- a/test/test.py +++ b/test/test.py @@ -99,7 +99,7 @@ print(denyOutputVerbose) # Fail direct hsu call: print(machine.fail("sudo -u alice -i hsu")) -# Verify PrintBaseError behaviour: +# Verify hsu fault behaviour: if denyOutput != "hsu: uid 1001 is not in the hsurc file\n": raise Exception(f"unexpected deny output:\n{denyOutput}") if denyOutputVerbose != "hsu: uid 1001 is not in the hsurc file\nhakurei: *cannot obtain uid from setuid wrapper: permission denied\n":