diff --git a/cmd/hakurei/command.go b/cmd/hakurei/command.go index 213cc41..187ed5d 100644 --- a/cmd/hakurei/command.go +++ b/cmd/hakurei/command.go @@ -3,7 +3,6 @@ package main import ( "context" "encoding/json" - "errors" "fmt" "io" "log" @@ -13,6 +12,7 @@ import ( "strconv" "sync" "time" + _ "unsafe" "hakurei.app/command" "hakurei.app/container/check" @@ -25,6 +25,9 @@ import ( "hakurei.app/system/dbus" ) +//go:linkname optionalErrorUnwrap hakurei.app/container.optionalErrorUnwrap +func optionalErrorUnwrap(_ error) error + func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErrs, out io.Writer) command.Command { var ( flagVerbose bool @@ -115,7 +118,7 @@ func buildCommand(ctx context.Context, msg message.Msg, early *earlyHardeningErr progPath := shell if len(args) > 0 { if p, err := exec.LookPath(args[0]); err != nil { - log.Fatal(errors.Unwrap(err)) + log.Fatal(optionalErrorUnwrap(err)) return err } else if progPath, err = check.NewAbs(p); err != nil { log.Fatal(err.Error()) diff --git a/cmd/hpkg/app.go b/cmd/hpkg/app.go index e8bd8b9..d03c8b0 100644 --- a/cmd/hpkg/app.go +++ b/cmd/hpkg/app.go @@ -91,7 +91,7 @@ func (app *appInfo) toHst(pathSet *appPathSet, pathname *check.Absolute, argv [] {FilesystemConfig: &hst.FSLink{Target: pathCurrentSystem, Linkname: app.CurrentSystem.String()}}, {FilesystemConfig: &hst.FSLink{Target: pathBin, Linkname: pathSwBin.String()}}, {FilesystemConfig: &hst.FSLink{Target: fhs.AbsUsrBin, Linkname: pathSwBin.String()}}, - {FilesystemConfig: &hst.FSBind{Source: pathSet.metaPath, Target: hst.AbsTmp.Append("app")}}, + {FilesystemConfig: &hst.FSBind{Source: pathSet.metaPath, Target: hst.AbsPrivateTmp.Append("app")}}, {FilesystemConfig: &hst.FSBind{Source: fhs.AbsEtc.Append("resolv.conf"), Optional: true}}, {FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("block"), Optional: true}}, {FilesystemConfig: &hst.FSBind{Source: fhs.AbsSys.Append("bus"), Optional: true}}, diff --git a/cmd/hpkg/main.go b/cmd/hpkg/main.go index e3346bf..757dc14 100644 --- a/cmd/hpkg/main.go +++ b/cmd/hpkg/main.go @@ -162,7 +162,7 @@ func main() { withCacheDir(ctx, msg, "install", []string{ // export inner bundle path in the environment - "export BUNDLE=" + hst.Tmp + "/bundle", + "export BUNDLE=" + hst.PrivateTmp + "/bundle", // replace inner /etc "mkdir -p etc", "chmod -R +w etc", @@ -309,7 +309,7 @@ func main() { if a.GPU { config.Container.Filesystem = append(config.Container.Filesystem, - hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath.Append(".nixGL"), Target: hst.AbsTmp.Append("nixGL")}}) + hst.FilesystemConfigJSON{FilesystemConfig: &hst.FSBind{Source: pathSet.nixPath.Append(".nixGL"), Target: hst.AbsPrivateTmp.Append("nixGL")}}) appendGPUFilesystem(config) } diff --git a/cmd/hpkg/with.go b/cmd/hpkg/with.go index cb86f50..5cb1533 100644 --- a/cmd/hpkg/with.go +++ b/cmd/hpkg/with.go @@ -88,7 +88,7 @@ func withCacheDir( {FilesystemConfig: &hst.FSLink{Target: pathCurrentSystem, Linkname: app.CurrentSystem.String()}}, {FilesystemConfig: &hst.FSLink{Target: pathBin, Linkname: pathSwBin.String()}}, {FilesystemConfig: &hst.FSLink{Target: fhs.AbsUsrBin, Linkname: pathSwBin.String()}}, - {FilesystemConfig: &hst.FSBind{Source: workDir, Target: hst.AbsTmp.Append("bundle")}}, + {FilesystemConfig: &hst.FSBind{Source: workDir, Target: hst.AbsPrivateTmp.Append("bundle")}}, {FilesystemConfig: &hst.FSBind{Target: pathDataData.Append(app.ID, "cache"), Source: pathSet.cacheDir, Write: true, Ensure: true}}, }, diff --git a/container/container_test.go b/container/container_test.go index 6a85869..bc90d8f 100644 --- a/container/container_test.go +++ b/container/container_test.go @@ -219,10 +219,10 @@ var containerTestCases = []struct { {"tmpfs", true, false, false, true, earlyOps(new(container.Ops). - Tmpfs(hst.AbsTmp, 0, 0755), + Tmpfs(hst.AbsPrivateTmp, 0, 0755), ), earlyMnt( - ent("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", ignore), + ent("/", hst.PrivateTmp, "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", ignore), ), 9, 9, nil, 0, bits.PresetStrict}, @@ -276,7 +276,7 @@ var containerTestCases = []struct { } return new(container.Ops). - Overlay(hst.AbsTmp, upper, work, lower0, lower1), + Overlay(hst.AbsPrivateTmp, upper, work, lower0, lower1), context.WithValue(context.WithValue(context.WithValue(context.WithValue(t.Context(), testVal("lower1"), lower1), testVal("lower0"), lower0), @@ -285,7 +285,7 @@ var containerTestCases = []struct { }, func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry { return []*vfs.MountInfoEntry{ - ent("/", hst.Tmp, "rw", "overlay", "overlay", + ent("/", hst.PrivateTmp, "rw", "overlay", "overlay", "rw,lowerdir="+ container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+ container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+ @@ -311,13 +311,13 @@ var containerTestCases = []struct { } return new(container.Ops). - OverlayEphemeral(hst.AbsTmp, lower0, lower1), + OverlayEphemeral(hst.AbsPrivateTmp, lower0, lower1), t.Context() }, func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry { return []*vfs.MountInfoEntry{ // contains random suffix - ent("/", hst.Tmp, "rw", "overlay", "overlay", ignore), + ent("/", hst.PrivateTmp, "rw", "overlay", "overlay", ignore), } }, 1 << 3, 1 << 14, nil, 0, bits.PresetStrict}, @@ -334,14 +334,14 @@ var containerTestCases = []struct { } } return new(container.Ops). - OverlayReadonly(hst.AbsTmp, lower0, lower1), + OverlayReadonly(hst.AbsPrivateTmp, lower0, lower1), context.WithValue(context.WithValue(t.Context(), testVal("lower1"), lower1), testVal("lower0"), lower0) }, func(t *testing.T, ctx context.Context) []*vfs.MountInfoEntry { return []*vfs.MountInfoEntry{ - ent("/", hst.Tmp, "rw", "overlay", "overlay", + ent("/", hst.PrivateTmp, "rw", "overlay", "overlay", "ro,lowerdir="+ container.InternalToHostOvlEscape(ctx.Value(testVal("lower0")).(*check.Absolute).String())+":"+ container.InternalToHostOvlEscape(ctx.Value(testVal("lower1")).(*check.Absolute).String())+ diff --git a/hst/config.go b/hst/config.go index 9d0ef67..08a23f0 100644 --- a/hst/config.go +++ b/hst/config.go @@ -8,9 +8,11 @@ import ( "hakurei.app/container/check" ) -const Tmp = "/.hakurei" +// PrivateTmp is a private writable path in a hakurei container. +const PrivateTmp = "/.hakurei" -var AbsTmp = check.MustAbs(Tmp) +// AbsPrivateTmp is a [check.Absolute] representation of [PrivateTmp]. +var AbsPrivateTmp = check.MustAbs(PrivateTmp) const ( // WaitDelayDefault is used when WaitDelay has its zero value. diff --git a/hst/config_test.go b/hst/config_test.go index eba2b79..211bd1c 100644 --- a/hst/config_test.go +++ b/hst/config_test.go @@ -62,8 +62,8 @@ func TestExtraPermConfig(t *testing.T) { {"nil path", &hst.ExtraPermConfig{Path: nil}, ""}, {"r", &hst.ExtraPermConfig{Path: fhs.AbsRoot, Read: true}, "r--:/"}, {"r+", &hst.ExtraPermConfig{Ensure: true, Path: fhs.AbsRoot, Read: true}, "r--+:/"}, - {"w", &hst.ExtraPermConfig{Path: hst.AbsTmp, Write: true}, "-w-:/.hakurei"}, - {"w+", &hst.ExtraPermConfig{Ensure: true, Path: hst.AbsTmp, Write: true}, "-w-+:/.hakurei"}, + {"w", &hst.ExtraPermConfig{Path: hst.AbsPrivateTmp, Write: true}, "-w-:/.hakurei"}, + {"w+", &hst.ExtraPermConfig{Ensure: true, Path: hst.AbsPrivateTmp, Write: true}, "-w-+:/.hakurei"}, {"x", &hst.ExtraPermConfig{Path: fhs.AbsRunUser, Execute: true}, "--x:/run/user/"}, {"x+", &hst.ExtraPermConfig{Ensure: true, Path: fhs.AbsRunUser, Execute: true}, "--x+:/run/user/"}, {"rwx", &hst.ExtraPermConfig{Path: fhs.AbsTmp, Read: true, Write: true, Execute: true}, "rwx:/tmp/"}, diff --git a/hst/fsephemeral_test.go b/hst/fsephemeral_test.go index ed8bbf4..4bda316 100644 --- a/hst/fsephemeral_test.go +++ b/hst/fsephemeral_test.go @@ -36,15 +36,15 @@ func TestFSEphemeral(t *testing.T) { "+ephemeral(-rwxr-xr-x):/run/nscd"}, {"negative size", &hst.FSEphemeral{ - Target: hst.AbsTmp, + Target: hst.AbsPrivateTmp, Write: true, Size: -1, }, true, container.Ops{&container.MountTmpfsOp{ FSName: "ephemeral", - Path: hst.AbsTmp, + Path: hst.AbsPrivateTmp, Flags: syscall.MS_NOSUID | syscall.MS_NODEV, Perm: 0755, - }}, hst.AbsTmp, nil, + }}, hst.AbsPrivateTmp, nil, "w+ephemeral(-rwxr-xr-x):/.hakurei"}, }) } diff --git a/internal/app/app_test.go b/internal/app/app_test.go index bfa42eb..8fbe011 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -98,7 +98,7 @@ func TestApp(t *testing.T) { Ops: new(container.Ops). Root(m("/"), bits.BindWritable). Proc(m("/proc/")). - Tmpfs(hst.AbsTmp, 4096, 0755). + Tmpfs(hst.AbsPrivateTmp, 4096, 0755). DevWritable(m("/dev/"), true). Tmpfs(m("/dev/shm"), 0, 01777). Bind(m("/dev/kvm"), m("/dev/kvm"), bits.BindWritable|bits.BindDevice|bits.BindOptional). @@ -252,7 +252,7 @@ func TestApp(t *testing.T) { "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/65534/bus", "DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket", "HOME=/home/chronos", - "PULSE_COOKIE=" + hst.Tmp + "/pulse-cookie", + "PULSE_COOKIE=" + hst.PrivateTmp + "/pulse-cookie", "PULSE_SERVER=unix:/run/user/65534/pulse/native", "SHELL=/run/current-system/sw/bin/zsh", "TERM=xterm-256color", @@ -265,7 +265,7 @@ func TestApp(t *testing.T) { Ops: new(container.Ops). Root(m("/"), bits.BindWritable). Proc(m("/proc/")). - Tmpfs(hst.AbsTmp, 4096, 0755). + Tmpfs(hst.AbsPrivateTmp, 4096, 0755). DevWritable(m("/dev/"), true). Tmpfs(m("/dev/shm"), 0, 01777). Bind(m("/dev/dri"), m("/dev/dri"), bits.BindWritable|bits.BindDevice|bits.BindOptional). @@ -282,7 +282,7 @@ func TestApp(t *testing.T) { Place(m("/etc/group"), []byte("hakurei:x:65534:\n")). Bind(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/65534/wayland-0"), 0). Bind(m("/run/user/1971/hakurei/ebf083d1b175911782d413369b64ce7c/pulse"), m("/run/user/65534/pulse/native"), 0). - Place(m(hst.Tmp+"/pulse-cookie"), bytes.Repeat([]byte{0}, pulseCookieSizeMax)). + Place(m(hst.PrivateTmp+"/pulse-cookie"), bytes.Repeat([]byte{0}, pulseCookieSizeMax)). Bind(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/bus"), m("/run/user/65534/bus"), 0). Bind(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/system_bus_socket"), m("/run/dbus/system_bus_socket"), 0). Remount(m("/"), syscall.MS_RDONLY), @@ -396,7 +396,7 @@ func TestApp(t *testing.T) { "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1971/bus", "DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket", "HOME=/var/lib/persist/module/hakurei/0/1", - "PULSE_COOKIE=" + hst.Tmp + "/pulse-cookie", + "PULSE_COOKIE=" + hst.PrivateTmp + "/pulse-cookie", "PULSE_SERVER=unix:/run/user/1971/pulse/native", "SHELL=/run/current-system/sw/bin/zsh", "TERM=xterm-256color", @@ -408,7 +408,7 @@ func TestApp(t *testing.T) { }, Ops: new(container.Ops). Proc(m("/proc/")). - Tmpfs(hst.AbsTmp, 4096, 0755). + Tmpfs(hst.AbsPrivateTmp, 4096, 0755). DevWritable(m("/dev/"), true). Tmpfs(m("/dev/shm"), 0, 01777). Bind(m("/bin"), m("/bin"), 0). @@ -432,7 +432,7 @@ func TestApp(t *testing.T) { Place(m("/etc/group"), []byte("hakurei:x:100:\n")). Bind(m("/run/user/1971/wayland-0"), m("/run/user/1971/wayland-0"), 0). Bind(m("/run/user/1971/hakurei/8e2c76b066dabe574cf073bdb46eb5c1/pulse"), m("/run/user/1971/pulse/native"), 0). - Place(m(hst.Tmp+"/pulse-cookie"), bytes.Repeat([]byte{0}, pulseCookieSizeMax)). + Place(m(hst.PrivateTmp+"/pulse-cookie"), bytes.Repeat([]byte{0}, pulseCookieSizeMax)). Bind(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/bus"), m("/run/user/1971/bus"), 0). Bind(m("/tmp/hakurei.0/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket"), m("/run/dbus/system_bus_socket"), 0). Remount(m("/"), syscall.MS_RDONLY), diff --git a/internal/app/spcontainer.go b/internal/app/spcontainer.go index 62fffc8..62c4f4f 100644 --- a/internal/app/spcontainer.go +++ b/internal/app/spcontainer.go @@ -105,7 +105,7 @@ func (s *spParamsOp) toContainer(state *outcomeStateParams) error { // early mount points state.params. Proc(fhs.AbsProc). - Tmpfs(hst.AbsTmp, 1<<12, 0755) + Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755) if !state.Container.Device { state.params.DevWritable(fhs.AbsDev, true) } else { diff --git a/internal/app/spcontainer_test.go b/internal/app/spcontainer_test.go index 653fba1..bcb1792 100644 --- a/internal/app/spcontainer_test.go +++ b/internal/app/spcontainer_test.go @@ -69,7 +69,7 @@ func TestSpParamsOp(t *testing.T) { Gid: 100, Ops: new(container.Ops). Root(m("/var/lib/hakurei/base/org.debian"), bits.BindWritable). - Proc(fhs.AbsProc).Tmpfs(hst.AbsTmp, 1<<12, 0755). + Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755). DevWritable(fhs.AbsDev, true). Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777), }, func(t *testing.T, state *outcomeStateParams) { @@ -114,7 +114,7 @@ func TestSpParamsOp(t *testing.T) { Gid: 100, Ops: new(container.Ops). Root(m("/var/lib/hakurei/base/org.debian"), bits.BindWritable). - Proc(fhs.AbsProc).Tmpfs(hst.AbsTmp, 1<<12, 0755). + Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755). Bind(fhs.AbsDev, fhs.AbsDev, bits.BindWritable|bits.BindDevice). Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777), }, func(t *testing.T, state *outcomeStateParams) { diff --git a/internal/app/sppulse.go b/internal/app/sppulse.go index 8a2e753..a9ef6ee 100644 --- a/internal/app/sppulse.go +++ b/internal/app/sppulse.go @@ -160,7 +160,7 @@ func (s *spPulseOp) toContainer(state *outcomeStateParams) error { state.env["PULSE_SERVER"] = "unix:" + innerPulseSocket.String() if s.Cookie != nil { - innerDst := hst.AbsTmp.Append("/pulse-cookie") + innerDst := hst.AbsPrivateTmp.Append("/pulse-cookie") state.env["PULSE_COOKIE"] = innerDst.String() state.params.Place(innerDst, s.Cookie[:]) }