From af0899de9640b4336050b07b739818fdc3add08b Mon Sep 17 00:00:00 2001 From: Ophestra Date: Fri, 1 Aug 2025 21:23:52 +0900 Subject: [PATCH] hst/container: mount tmpfs via magic src string There's often good reason to mount tmpfs in the container. Signed-off-by: Ophestra --- hst/container.go | 14 ++++++++++++++ internal/app/app_pd_linux_test.go | 8 ++++---- internal/app/container_linux.go | 14 ++++++++++++++ internal/app/seal_linux.go | 11 ++++++----- test/sandbox/case/pd.nix | 2 +- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/hst/container.go b/hst/container.go index 5622992..9ca14a8 100644 --- a/hst/container.go +++ b/hst/container.go @@ -6,6 +6,20 @@ import ( "hakurei.app/container/seccomp" ) +const ( + // SourceTmpfs causes tmpfs to be mounted on [FilesystemConfig.Dst] + // when assigned to [FilesystemConfig.Src]. + SourceTmpfs = "tmpfs" + + // TmpfsPerm is the permission bits for tmpfs mount points + // configured through [FilesystemConfig]. + TmpfsPerm = 0755 + + // TmpfsSize is the size for tmpfs mount points + // configured through [FilesystemConfig]. + TmpfsSize = 0 +) + type ( // ContainerConfig describes the container configuration baseline to which the app implementation adds upon. ContainerConfig struct { diff --git a/internal/app/app_pd_linux_test.go b/internal/app/app_pd_linux_test.go index aea59d1..7f0049b 100644 --- a/internal/app/app_pd_linux_test.go +++ b/internal/app/app_pd_linux_test.go @@ -47,6 +47,7 @@ var testCasesPd = []sealTestCase{ Tmpfs(hst.Tmp, 4096, 0755). Dev("/dev").Mqueue("/dev/mqueue"). Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional). + Readonly("/var/run/nscd", 0755). Tmpfs("/run/user/1971", 8192, 0755). Tmpfs("/run/dbus", 8192, 0755). Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac"). @@ -55,8 +56,7 @@ var testCasesPd = []sealTestCase{ Bind("/tmp/hakurei.1971/tmpdir/0", "/tmp", container.BindWritable). Bind("/home/chronos", "/home/chronos", container.BindWritable). Place("/etc/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")). - Place("/etc/group", []byte("hakurei:x:65534:\n")). - Tmpfs("/var/run/nscd", 8192, 0755), + Place("/etc/group", []byte("hakurei:x:65534:\n")), SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyDevel, HostNet: true, RetainSession: true, @@ -181,6 +181,7 @@ var testCasesPd = []sealTestCase{ Dev("/dev").Mqueue("/dev/mqueue"). Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional). Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional). + Readonly("/var/run/nscd", 0755). Tmpfs("/run/user/1971", 8192, 0755). Tmpfs("/run/dbus", 8192, 0755). Etc("/etc", "ebf083d1b175911782d413369b64ce7c"). @@ -194,8 +195,7 @@ var testCasesPd = []sealTestCase{ Bind("/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c/pulse", "/run/user/65534/pulse/native", 0). Place(hst.Tmp+"/pulse-cookie", nil). Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/bus", "/run/user/65534/bus", 0). - Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", "/run/dbus/system_bus_socket", 0). - Tmpfs("/var/run/nscd", 8192, 0755), + Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", "/run/dbus/system_bus_socket", 0), SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyDevel, HostNet: true, RetainSession: true, diff --git a/internal/app/container_linux.go b/internal/app/container_linux.go index cd9448a..09909d8 100644 --- a/internal/app/container_linux.go +++ b/internal/app/container_linux.go @@ -156,6 +156,20 @@ func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, uid, gid continue } + // special filesystems + switch c.Src { + case hst.SourceTmpfs: + if !path.IsAbs(c.Dst) { + return nil, nil, fmt.Errorf("tmpfs dst %q is not absolute", c.Dst) + } + if c.Write { + params.Tmpfs(c.Dst, hst.TmpfsSize, hst.TmpfsPerm) + } else { + params.Readonly(c.Dst, hst.TmpfsPerm) + } + continue + } + if !path.IsAbs(c.Src) { return nil, nil, fmt.Errorf("src path %q is not absolute", c.Src) } diff --git a/internal/app/seal_linux.go b/internal/app/seal_linux.go index d020697..cc92db2 100644 --- a/internal/app/seal_linux.go +++ b/internal/app/seal_linux.go @@ -246,11 +246,6 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co RootFlags: container.BindWritable, } - // hide nscd from sandbox if present - nscd := "/var/run/nscd" - if _, err := sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) { - conf.Cover = append(conf.Cover, nscd) - } // bind GPU stuff if config.Enablements&(system.EX11|system.EWayland) != 0 { conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/dri", Device: true}) @@ -258,6 +253,12 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co // opportunistically bind kvm conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/kvm", Device: true}) + // hide nscd from container if present + const nscd = "/var/run/nscd" + if _, err := sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) { + conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Dst: nscd, Src: hst.SourceTmpfs}) + } + config.Container = conf } diff --git a/test/sandbox/case/pd.nix b/test/sandbox/case/pd.nix index 569e325..950afdf 100644 --- a/test/sandbox/case/pd.nix +++ b/test/sandbox/case/pd.nix @@ -181,6 +181,7 @@ (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 "/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 "/" "/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 "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") @@ -190,7 +191,6 @@ (ent "/var/lib/hakurei/u0/a0" "/var/lib/hakurei/u0/a0" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000") (ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000") - (ent "/" "/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000") ]; seccomp = true;