internal/outcome: attempt nscd path-hiding if present
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m46s
Test / ShareFS (push) Successful in 3m56s
Test / Hakurei (push) Successful in 4m9s
Test / Sandbox (race detector) (push) Successful in 5m42s
Test / Hakurei (race detector) (push) Successful in 6m50s
Test / Flake checks (push) Successful in 1m9s
Test / Create distribution (push) Successful in 52s
Test / Sandbox (push) Successful in 2m46s
Test / ShareFS (push) Successful in 3m56s
Test / Hakurei (push) Successful in 4m9s
Test / Sandbox (race detector) (push) Successful in 5m42s
Test / Hakurei (race detector) (push) Successful in 6m50s
Test / Flake checks (push) Successful in 1m9s
This avoids creating the mount point on musl setups which accomplishes nothing and can run into permission problems. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Vendored
+24
-4
@@ -1,21 +1,29 @@
|
||||
// Package env provides the [Paths] struct for efficiently building paths from the environment.
|
||||
// Package env provides the [Paths] struct for efficiently building paths from
|
||||
// the environment.
|
||||
package env
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"hakurei.app/check"
|
||||
"hakurei.app/fhs"
|
||||
"hakurei.app/hst"
|
||||
)
|
||||
|
||||
const VarRunNscd = fhs.Var + "run/nscd"
|
||||
|
||||
// Paths holds paths copied from the environment and is used to create [hst.Paths].
|
||||
type Paths struct {
|
||||
// TempDir is returned by [os.TempDir].
|
||||
TempDir *check.Absolute
|
||||
// RuntimePath is copied from $XDG_RUNTIME_DIR.
|
||||
RuntimePath *check.Absolute
|
||||
// Whether [VarRunNscd] is a directory.
|
||||
HasNscd bool
|
||||
}
|
||||
|
||||
// Copy expands [Paths] into [hst.Paths].
|
||||
@@ -37,14 +45,17 @@ func (env *Paths) Copy(v *hst.Paths, userid int) {
|
||||
}
|
||||
|
||||
// CopyPaths returns a populated [Paths].
|
||||
func CopyPaths() *Paths { return CopyPathsFunc(log.Fatalf, os.TempDir, os.Getenv) }
|
||||
func CopyPaths() *Paths {
|
||||
return CopyPathsFunc(log.Fatalf, os.TempDir, os.Getenv, os.Stat)
|
||||
}
|
||||
|
||||
// CopyPathsFunc returns a populated [Paths],
|
||||
// using the provided [log.Fatalf], [os.TempDir], [os.Getenv] functions.
|
||||
// CopyPathsFunc returns a populated [Paths], using the provided [log.Fatalf],
|
||||
// [os.TempDir], [os.Getenv] functions.
|
||||
func CopyPathsFunc(
|
||||
fatalf func(format string, v ...any),
|
||||
tempdir func() string,
|
||||
getenv func(key string) string,
|
||||
stat func(name string) (fs.FileInfo, error),
|
||||
) *Paths {
|
||||
const xdgRuntimeDir = "XDG_RUNTIME_DIR"
|
||||
|
||||
@@ -61,5 +72,14 @@ func CopyPathsFunc(
|
||||
env.RuntimePath = a
|
||||
}
|
||||
|
||||
if fi, err := stat(VarRunNscd); err != nil {
|
||||
if !errors.Is(err, fs.ErrNotExist) {
|
||||
fatalf("%v", err)
|
||||
panic("unreachable")
|
||||
}
|
||||
} else {
|
||||
env.HasNscd = fi.IsDir()
|
||||
}
|
||||
|
||||
return &env
|
||||
}
|
||||
|
||||
Vendored
+4
-1
@@ -2,6 +2,7 @@ package env_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
@@ -104,7 +105,9 @@ func TestCopyPaths(t *testing.T) {
|
||||
t.Fatalf("fatalf: %q, want %q", got, tc.fatal)
|
||||
}
|
||||
panic(stub.PanicExit)
|
||||
}, func() string { return tc.tmp }, func(key string) string { return tc.env[key] })
|
||||
}, func() string { return tc.tmp }, func(key string) string { return tc.env[key] }, func(name string) (fs.FileInfo, error) {
|
||||
return nil, fs.ErrNotExist
|
||||
})
|
||||
|
||||
if tc.fatal != "" {
|
||||
t.Fatalf("copyPaths: expected fatal %q", tc.fatal)
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"hakurei.app/container/seccomp"
|
||||
"hakurei.app/container/std"
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/env"
|
||||
"hakurei.app/internal/stub"
|
||||
"hakurei.app/internal/system"
|
||||
"hakurei.app/message"
|
||||
@@ -174,6 +175,7 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) {
|
||||
call("cmdOutput", stub.ExpectArgs{container.Nonexistent, os.Stderr, []string{}, "/"}, []byte("0"), nil),
|
||||
call("tempdir", stub.ExpectArgs{}, container.Nonexistent+"/tmp", nil),
|
||||
call("lookupEnv", stub.ExpectArgs{"XDG_RUNTIME_DIR"}, wantRuntimePath, nil),
|
||||
call("stat", stub.ExpectArgs{env.VarRunNscd}, stubFileInfoIsDir(true), nil),
|
||||
call("getuid", stub.ExpectArgs{}, 1000, nil),
|
||||
call("getgid", stub.ExpectArgs{}, 100, nil),
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ func newOutcomeState(k syscallDispatcher, msg message.Msg, id *hst.ID, config *h
|
||||
Paths: env.CopyPathsFunc(k.fatalf, k.tempdir, func(key string) string {
|
||||
v, _ := k.lookupEnv(key)
|
||||
return v
|
||||
}),
|
||||
}, k.stat),
|
||||
Container: config.Container,
|
||||
}
|
||||
|
||||
|
||||
@@ -710,7 +710,7 @@ func (k *stubNixOS) lookupEnv(key string) (string, bool) {
|
||||
func (k *stubNixOS) stat(name string) (fs.FileInfo, error) {
|
||||
switch name {
|
||||
case "/var/run/nscd":
|
||||
return nil, nil
|
||||
return stubFileInfoIsDir(true), nil
|
||||
case "/run/user/1971/pulse":
|
||||
return nil, nil
|
||||
case "/run/user/1971/pulse/native":
|
||||
|
||||
@@ -18,13 +18,12 @@ import (
|
||||
"hakurei.app/hst"
|
||||
"hakurei.app/internal/acl"
|
||||
"hakurei.app/internal/dbus"
|
||||
"hakurei.app/internal/env"
|
||||
"hakurei.app/internal/system"
|
||||
"hakurei.app/internal/validate"
|
||||
"hakurei.app/message"
|
||||
)
|
||||
|
||||
const varRunNscd = fhs.Var + "run/nscd"
|
||||
|
||||
func init() { gob.Register(new(spParamsOp)) }
|
||||
|
||||
// spParamsOp initialises unordered fields of [container.Params] and the
|
||||
@@ -136,17 +135,23 @@ type spFilesystemOp struct {
|
||||
}
|
||||
|
||||
func (s *spFilesystemOp) toSystem(state *outcomeStateSys) error {
|
||||
/* retrieve paths and hide them if they're made available in the sandbox;
|
||||
|
||||
this feature tries to improve user experience of permissive defaults, and
|
||||
to warn about issues in custom configuration; it is NOT a security feature
|
||||
and should not be treated as such, ALWAYS be careful with what you bind */
|
||||
// retrieve paths and hide them if they're made available in the sandbox
|
||||
//
|
||||
// this feature tries to improve user experience of permissive defaults, and
|
||||
// to warn about issues in custom configuration; it is NOT a security feature
|
||||
// and should not be treated as such, ALWAYS be careful with what you bind
|
||||
hidePaths := []string{
|
||||
state.sc.RuntimePath.String(),
|
||||
state.sc.SharePath.String(),
|
||||
}
|
||||
|
||||
// this causes emulated passwd database to be bypassed on some /etc/ setups
|
||||
varRunNscd,
|
||||
if state.Paths == nil || state.HasNscd {
|
||||
hidePaths = append(hidePaths,
|
||||
// this causes emulated passwd database to be bypassed on some /etc/
|
||||
// setups, made optional to avoid needlessly creating it on
|
||||
// non-glibc systems when invoking permissive defaults
|
||||
env.VarRunNscd,
|
||||
)
|
||||
}
|
||||
|
||||
// dbus.Address does not go through syscallDispatcher
|
||||
|
||||
Reference in New Issue
Block a user