diff --git a/fst/sandbox.go b/fst/sandbox.go index cc98ec8..2a6f347 100644 --- a/fst/sandbox.go +++ b/fst/sandbox.go @@ -239,21 +239,6 @@ func (s *SandboxConfig) ToContainer(sys SandboxSys, uid, gid *int) (*sandbox.Par container.Link(l[0], l[1]) } - // perf: this might work better if implemented as a setup op in container init - if !s.AutoEtc { - if s.Etc != "" { - container.Bind(s.Etc, "/etc", 0) - } - } else { - const hostEtc = Tmp + "/etc" - - etcPath := s.Etc - if etcPath == "" { - etcPath = "/etc" - } - container.Bind(etcPath, hostEtc, 0).Etc(hostEtc) - } - return container, maps.Clone(s.Env), nil } diff --git a/internal/app/app_nixos_test.go b/internal/app/app_nixos_test.go index 3017551..88efa7d 100644 --- a/internal/app/app_nixos_test.go +++ b/internal/app/app_nixos_test.go @@ -124,8 +124,7 @@ var testCasesNixos = []sealTestCase{ Bind("/sys/devices", "/sys/devices", sandbox.BindOptional). Bind("/run/opengl-driver", "/run/opengl-driver", 0). Bind("/dev/dri", "/dev/dri", sandbox.BindDevice|sandbox.BindWritable|sandbox.BindOptional). - Bind("/etc", fst.Tmp+"/etc", 0). - Etc(fst.Tmp+"/etc"). + Etc("/etc", "8e2c76b066dabe574cf073bdb46eb5c1"). Tmpfs("/run/user", 4096, 0755). Tmpfs("/run/user/1971", 8388608, 0700). Bind("/tmp/fortify.1971/tmpdir/1", "/tmp", sandbox.BindWritable). diff --git a/internal/app/app_pd_test.go b/internal/app/app_pd_test.go index fc796ec..ac07d70 100644 --- a/internal/app/app_pd_test.go +++ b/internal/app/app_pd_test.go @@ -63,8 +63,7 @@ var testCasesPd = []sealTestCase{ Bind("/dev/kvm", "/dev/kvm", sandbox.BindWritable|sandbox.BindDevice|sandbox.BindOptional). Tmpfs("/run/user/1971", 8192, 0755). Tmpfs("/run/dbus", 8192, 0755). - Bind("/etc", fst.Tmp+"/etc", 0). - Etc(fst.Tmp+"/etc"). + Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac"). Tmpfs("/run/user", 4096, 0755). Tmpfs("/run/user/65534", 8388608, 0700). Bind("/tmp/fortify.1971/tmpdir/0", "/tmp", sandbox.BindWritable). @@ -206,8 +205,7 @@ var testCasesPd = []sealTestCase{ Bind("/dev/kvm", "/dev/kvm", sandbox.BindWritable|sandbox.BindDevice|sandbox.BindOptional). Tmpfs("/run/user/1971", 8192, 0755). Tmpfs("/run/dbus", 8192, 0755). - Bind("/etc", fst.Tmp+"/etc", 0). - Etc(fst.Tmp+"/etc"). + Etc("/etc", "ebf083d1b175911782d413369b64ce7c"). Tmpfs("/run/user", 4096, 0755). Tmpfs("/run/user/65534", 8388608, 0700). Bind("/tmp/fortify.1971/tmpdir/9", "/tmp", sandbox.BindWritable). diff --git a/internal/app/seal.go b/internal/app/seal.go index 4c8fbc7..3c93b34 100644 --- a/internal/app/seal.go +++ b/internal/app/seal.go @@ -301,6 +301,18 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *fst.Co } } + if !config.Confinement.Sandbox.AutoEtc { + if config.Confinement.Sandbox.Etc != "" { + seal.container.Bind(config.Confinement.Sandbox.Etc, "/etc", 0) + } + } else { + etcPath := config.Confinement.Sandbox.Etc + if etcPath == "" { + etcPath = "/etc" + } + seal.container.Etc(etcPath, seal.id.String()) + } + // inner XDG_RUNTIME_DIR default formatting of `/run/user/%d` as mapped uid innerRuntimeDir := path.Join("/run/user", mapuid.String()) seal.container.Tmpfs("/run/user", 1<<12, 0755) diff --git a/sandbox/ops.go b/sandbox/ops.go index fd56f61..de105ee 100644 --- a/sandbox/ops.go +++ b/sandbox/ops.go @@ -443,31 +443,26 @@ func (f *Ops) PlaceP(name string, dataP **[]byte) *Ops { func init() { gob.Register(new(AutoEtc)) } -// AutoEtc creates a toplevel symlink mirror of a directory in sysroot with /etc semantics. +// AutoEtc expands host /etc into a toplevel symlink mirror with /etc semantics. // This is not a generic setup op. It is implemented here to reduce ipc overhead. -type AutoEtc struct { - // this is an absolute path within sysroot - HostEtc string -} +type AutoEtc struct{ Prefix string } func (e *AutoEtc) early(*Params) error { return nil } func (e *AutoEtc) apply(*Params) error { - if !path.IsAbs(e.HostEtc) { - return msg.WrapErr(syscall.EBADE, - fmt.Sprintf("path %q is not absolute", e.HostEtc)) - } - const target = sysrootPath + "/etc/" + rel := e.hostRel() + "/" + if err := os.MkdirAll(target, 0755); err != nil { return wrapErrSelf(err) } - - if d, err := os.ReadDir(toSysroot(e.HostEtc)); err != nil { + if d, err := os.ReadDir(toSysroot(e.hostPath())); err != nil { return wrapErrSelf(err) } else { for _, ent := range d { n := ent.Name() switch n { + case ".host": + case "passwd": case "group": @@ -477,7 +472,7 @@ func (e *AutoEtc) apply(*Params) error { } default: - if err = os.Symlink(path.Join(e.HostEtc, n), target+n); err != nil { + if err = os.Symlink(rel+n, target+n); err != nil { return wrapErrSelf(err) } } @@ -486,11 +481,19 @@ func (e *AutoEtc) apply(*Params) error { return nil } +func (e *AutoEtc) hostPath() string { return "/etc/" + e.hostRel() } +func (e *AutoEtc) hostRel() string { return ".host/" + e.Prefix } func (e *AutoEtc) Is(op Op) bool { ve, ok := op.(*AutoEtc) return ok && ((e == nil && ve == nil) || (e != nil && ve != nil && *e == *ve)) } -func (*AutoEtc) prefix() string { return "setting up" } -func (e *AutoEtc) String() string { return fmt.Sprintf("auto etc via %s", e.HostEtc) } -func (f *Ops) Etc(host string) *Ops { *f = append(*f, &AutoEtc{host}); return f } +func (*AutoEtc) prefix() string { return "setting up" } +func (e *AutoEtc) String() string { return fmt.Sprintf("auto etc %s", e.Prefix) } +func (f *Ops) Etc(host, prefix string) *Ops { + e := &AutoEtc{prefix} + f.Mkdir("/etc", 0755) + f.Bind(host, e.hostPath(), 0) + *f = append(*f, e) + return f +} diff --git a/test/sandbox/case/mapuid.nix b/test/sandbox/case/mapuid.nix index ea3d5b2..94a8cb3 100644 --- a/test/sandbox/case/mapuid.nix +++ b/test/sandbox/case/mapuid.nix @@ -23,9 +23,7 @@ ]; fs = fs "dead" { - ".fortify" = fs "800001ed" { - etc = fs "800001ed" null null; - } null; + ".fortify" = fs "800001ed" { } null; bin = fs "800001ed" { sh = fs "80001ff" null null; } null; dev = fs "800001ed" { core = fs "80001ff" null null; @@ -54,6 +52,7 @@ } 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; @@ -213,7 +212,7 @@ (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 "/etc" "/.fortify/etc" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") + (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000003,gid=1000003") (ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8192k,mode=700,uid=1000003,gid=1000003") (ent "/tmp/fortify.1000/tmpdir/3" "/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 6e83b72..762d212 100644 --- a/test/sandbox/case/preset.nix +++ b/test/sandbox/case/preset.nix @@ -23,9 +23,7 @@ ]; fs = fs "dead" { - ".fortify" = fs "800001ed" { - etc = fs "800001ed" null null; - } null; + ".fortify" = fs "800001ed" { } null; bin = fs "800001ed" { sh = fs "80001ff" null null; } null; dev = fs "800001ed" { core = fs "80001ff" null null; @@ -54,6 +52,7 @@ } 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; @@ -213,7 +212,7 @@ (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 "/etc" "/.fortify/etc" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") + (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000001,gid=1000001") (ent "/" "/run/user/65534" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8192k,mode=700,uid=1000001,gid=1000001") (ent "/tmp/fortify.1000/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 19c2896..e323eca 100644 --- a/test/sandbox/case/tty.nix +++ b/test/sandbox/case/tty.nix @@ -23,9 +23,7 @@ ]; fs = fs "dead" { - ".fortify" = fs "800001ed" { - etc = fs "800001ed" null null; - } null; + ".fortify" = fs "800001ed" { } null; bin = fs "800001ed" { sh = fs "80001ff" null null; } null; dev = fs "800001ed" { console = fs "4200190" null null; @@ -55,6 +53,7 @@ } 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; @@ -215,7 +214,7 @@ (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 "/etc" "/.fortify/etc" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") + (ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw") (ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000002,gid=1000002") (ent "/" "/run/user/65534" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8192k,mode=700,uid=1000002,gid=1000002") (ent "/tmp/fortify.1000/tmpdir/2" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")