container: move out of toplevel
All checks were successful
Test / Create distribution (push) Successful in 32s
Test / Sandbox (push) Successful in 1m52s
Test / Sandbox (race detector) (push) Successful in 3m14s
Test / Planterette (push) Successful in 3m36s
Test / Hakurei (race detector) (push) Successful in 4m31s
Test / Hakurei (push) Successful in 2m3s
Test / Flake checks (push) Successful in 1m13s
All checks were successful
Test / Create distribution (push) Successful in 32s
Test / Sandbox (push) Successful in 1m52s
Test / Sandbox (race detector) (push) Successful in 3m14s
Test / Planterette (push) Successful in 3m36s
Test / Hakurei (race detector) (push) Successful in 4m31s
Test / Hakurei (push) Successful in 2m3s
Test / Flake checks (push) Successful in 1m13s
This allows slightly easier use of the vanity url. This also provides some disambiguation between low level containers and hakurei app containers. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
82561d62b6
commit
1b5ecd9eaf
@ -8,10 +8,10 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/sys"
|
"git.gensokyo.uk/security/hakurei/internal/sys"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
"git.gensokyo.uk/security/hakurei/system/dbus"
|
"git.gensokyo.uk/security/hakurei/system/dbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -21,12 +21,12 @@ const preallocateOpsCount = 1 << 5
|
|||||||
|
|
||||||
// NewContainer initialises [sandbox.Params] via [hst.ContainerConfig].
|
// NewContainer initialises [sandbox.Params] via [hst.ContainerConfig].
|
||||||
// Note that remaining container setup must be queued by the caller.
|
// Note that remaining container setup must be queued by the caller.
|
||||||
func NewContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*hakurei.Params, map[string]string, error) {
|
func NewContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*container.Params, map[string]string, error) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return nil, nil, syscall.EBADE
|
return nil, nil, syscall.EBADE
|
||||||
}
|
}
|
||||||
|
|
||||||
container := &hakurei.Params{
|
params := &container.Params{
|
||||||
Hostname: s.Hostname,
|
Hostname: s.Hostname,
|
||||||
SeccompFlags: s.SeccompFlags,
|
SeccompFlags: s.SeccompFlags,
|
||||||
SeccompPresets: s.SeccompPresets,
|
SeccompPresets: s.SeccompPresets,
|
||||||
@ -35,47 +35,47 @@ func NewContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*hakurei
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
ops := make(hakurei.Ops, 0, preallocateOpsCount+len(s.Filesystem)+len(s.Link)+len(s.Cover))
|
ops := make(container.Ops, 0, preallocateOpsCount+len(s.Filesystem)+len(s.Link)+len(s.Cover))
|
||||||
container.Ops = &ops
|
params.Ops = &ops
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Multiarch {
|
if s.Multiarch {
|
||||||
container.SeccompFlags |= seccomp.AllowMultiarch
|
params.SeccompFlags |= seccomp.AllowMultiarch
|
||||||
}
|
}
|
||||||
|
|
||||||
if !s.SeccompCompat {
|
if !s.SeccompCompat {
|
||||||
container.SeccompPresets |= seccomp.PresetExt
|
params.SeccompPresets |= seccomp.PresetExt
|
||||||
}
|
}
|
||||||
if !s.Devel {
|
if !s.Devel {
|
||||||
container.SeccompPresets |= seccomp.PresetDenyDevel
|
params.SeccompPresets |= seccomp.PresetDenyDevel
|
||||||
}
|
}
|
||||||
if !s.Userns {
|
if !s.Userns {
|
||||||
container.SeccompPresets |= seccomp.PresetDenyNS
|
params.SeccompPresets |= seccomp.PresetDenyNS
|
||||||
}
|
}
|
||||||
if !s.Tty {
|
if !s.Tty {
|
||||||
container.SeccompPresets |= seccomp.PresetDenyTTY
|
params.SeccompPresets |= seccomp.PresetDenyTTY
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.MapRealUID {
|
if s.MapRealUID {
|
||||||
/* some programs fail to connect to dbus session running as a different uid
|
/* some programs fail to connect to dbus session running as a different uid
|
||||||
so this workaround is introduced to map priv-side caller uid in container */
|
so this workaround is introduced to map priv-side caller uid in container */
|
||||||
container.Uid = os.Getuid()
|
params.Uid = os.Getuid()
|
||||||
*uid = container.Uid
|
*uid = params.Uid
|
||||||
container.Gid = os.Getgid()
|
params.Gid = os.Getgid()
|
||||||
*gid = container.Gid
|
*gid = params.Gid
|
||||||
} else {
|
} else {
|
||||||
*uid = hakurei.OverflowUid()
|
*uid = container.OverflowUid()
|
||||||
*gid = hakurei.OverflowGid()
|
*gid = container.OverflowGid()
|
||||||
}
|
}
|
||||||
|
|
||||||
container.
|
params.
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 1<<12, 0755)
|
Tmpfs(hst.Tmp, 1<<12, 0755)
|
||||||
|
|
||||||
if !s.Device {
|
if !s.Device {
|
||||||
container.Dev("/dev").Mqueue("/dev/mqueue")
|
params.Dev("/dev").Mqueue("/dev/mqueue")
|
||||||
} else {
|
} else {
|
||||||
container.Bind("/dev", "/dev", hakurei.BindWritable|hakurei.BindDevice)
|
params.Bind("/dev", "/dev", container.BindWritable|container.BindDevice)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* retrieve paths and hide them if they're made available in the sandbox;
|
/* retrieve paths and hide them if they're made available in the sandbox;
|
||||||
@ -154,29 +154,29 @@ func NewContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*hakurei
|
|||||||
|
|
||||||
var flags int
|
var flags int
|
||||||
if c.Write {
|
if c.Write {
|
||||||
flags |= hakurei.BindWritable
|
flags |= container.BindWritable
|
||||||
}
|
}
|
||||||
if c.Device {
|
if c.Device {
|
||||||
flags |= hakurei.BindDevice | hakurei.BindWritable
|
flags |= container.BindDevice | container.BindWritable
|
||||||
}
|
}
|
||||||
if !c.Must {
|
if !c.Must {
|
||||||
flags |= hakurei.BindOptional
|
flags |= container.BindOptional
|
||||||
}
|
}
|
||||||
container.Bind(c.Src, dest, flags)
|
params.Bind(c.Src, dest, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// cover matched paths
|
// cover matched paths
|
||||||
for i, ok := range hidePathMatch {
|
for i, ok := range hidePathMatch {
|
||||||
if ok {
|
if ok {
|
||||||
container.Tmpfs(hidePaths[i], 1<<13, 0755)
|
params.Tmpfs(hidePaths[i], 1<<13, 0755)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, l := range s.Link {
|
for _, l := range s.Link {
|
||||||
container.Link(l[0], l[1])
|
params.Link(l[0], l[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
return container, maps.Clone(s.Env), nil
|
return params, maps.Clone(s.Env), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func evalSymlinks(os sys.State, v *string) error {
|
func evalSymlinks(os sys.State, v *string) error {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package setuid_test
|
package setuid_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gensokyo.uk/security/hakurei"
|
|
||||||
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
"git.gensokyo.uk/security/hakurei/system/acl"
|
"git.gensokyo.uk/security/hakurei/system/acl"
|
||||||
"git.gensokyo.uk/security/hakurei/system/dbus"
|
"git.gensokyo.uk/security/hakurei/system/dbus"
|
||||||
@ -94,7 +94,7 @@ var testCasesNixos = []sealTestCase{
|
|||||||
}).
|
}).
|
||||||
UpdatePerm("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/bus", acl.Read, acl.Write).
|
UpdatePerm("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/bus", acl.Read, acl.Write).
|
||||||
UpdatePerm("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", acl.Read, acl.Write),
|
UpdatePerm("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", acl.Read, acl.Write),
|
||||||
&hakurei.Params{
|
&container.Params{
|
||||||
Uid: 1971,
|
Uid: 1971,
|
||||||
Gid: 100,
|
Gid: 100,
|
||||||
Dir: "/var/lib/persist/module/hakurei/0/1",
|
Dir: "/var/lib/persist/module/hakurei/0/1",
|
||||||
@ -114,7 +114,7 @@ var testCasesNixos = []sealTestCase{
|
|||||||
"XDG_SESSION_CLASS=user",
|
"XDG_SESSION_CLASS=user",
|
||||||
"XDG_SESSION_TYPE=tty",
|
"XDG_SESSION_TYPE=tty",
|
||||||
},
|
},
|
||||||
Ops: new(hakurei.Ops).
|
Ops: new(container.Ops).
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
Dev("/dev").Mqueue("/dev/mqueue").
|
Dev("/dev").Mqueue("/dev/mqueue").
|
||||||
@ -122,18 +122,18 @@ var testCasesNixos = []sealTestCase{
|
|||||||
Bind("/usr/bin", "/usr/bin", 0).
|
Bind("/usr/bin", "/usr/bin", 0).
|
||||||
Bind("/nix/store", "/nix/store", 0).
|
Bind("/nix/store", "/nix/store", 0).
|
||||||
Bind("/run/current-system", "/run/current-system", 0).
|
Bind("/run/current-system", "/run/current-system", 0).
|
||||||
Bind("/sys/block", "/sys/block", hakurei.BindOptional).
|
Bind("/sys/block", "/sys/block", container.BindOptional).
|
||||||
Bind("/sys/bus", "/sys/bus", hakurei.BindOptional).
|
Bind("/sys/bus", "/sys/bus", container.BindOptional).
|
||||||
Bind("/sys/class", "/sys/class", hakurei.BindOptional).
|
Bind("/sys/class", "/sys/class", container.BindOptional).
|
||||||
Bind("/sys/dev", "/sys/dev", hakurei.BindOptional).
|
Bind("/sys/dev", "/sys/dev", container.BindOptional).
|
||||||
Bind("/sys/devices", "/sys/devices", hakurei.BindOptional).
|
Bind("/sys/devices", "/sys/devices", container.BindOptional).
|
||||||
Bind("/run/opengl-driver", "/run/opengl-driver", 0).
|
Bind("/run/opengl-driver", "/run/opengl-driver", 0).
|
||||||
Bind("/dev/dri", "/dev/dri", hakurei.BindDevice|hakurei.BindWritable|hakurei.BindOptional).
|
Bind("/dev/dri", "/dev/dri", container.BindDevice|container.BindWritable|container.BindOptional).
|
||||||
Etc("/etc", "8e2c76b066dabe574cf073bdb46eb5c1").
|
Etc("/etc", "8e2c76b066dabe574cf073bdb46eb5c1").
|
||||||
Tmpfs("/run/user", 4096, 0755).
|
Tmpfs("/run/user", 4096, 0755).
|
||||||
Bind("/tmp/hakurei.1971/runtime/1", "/run/user/1971", hakurei.BindWritable).
|
Bind("/tmp/hakurei.1971/runtime/1", "/run/user/1971", container.BindWritable).
|
||||||
Bind("/tmp/hakurei.1971/tmpdir/1", "/tmp", hakurei.BindWritable).
|
Bind("/tmp/hakurei.1971/tmpdir/1", "/tmp", container.BindWritable).
|
||||||
Bind("/var/lib/persist/module/hakurei/0/1", "/var/lib/persist/module/hakurei/0/1", hakurei.BindWritable).
|
Bind("/var/lib/persist/module/hakurei/0/1", "/var/lib/persist/module/hakurei/0/1", container.BindWritable).
|
||||||
Place("/etc/passwd", []byte("u0_a1:x:1971:100:Hakurei:/var/lib/persist/module/hakurei/0/1:/run/current-system/sw/bin/zsh\n")).
|
Place("/etc/passwd", []byte("u0_a1:x:1971:100:Hakurei:/var/lib/persist/module/hakurei/0/1:/run/current-system/sw/bin/zsh\n")).
|
||||||
Place("/etc/group", []byte("hakurei:x:100:\n")).
|
Place("/etc/group", []byte("hakurei:x:100:\n")).
|
||||||
Bind("/run/user/1971/wayland-0", "/run/user/1971/wayland-0", 0).
|
Bind("/run/user/1971/wayland-0", "/run/user/1971/wayland-0", 0).
|
||||||
|
@ -3,10 +3,10 @@ package setuid_test
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
|
||||||
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
"git.gensokyo.uk/security/hakurei/system/acl"
|
"git.gensokyo.uk/security/hakurei/system/acl"
|
||||||
"git.gensokyo.uk/security/hakurei/system/dbus"
|
"git.gensokyo.uk/security/hakurei/system/dbus"
|
||||||
@ -28,7 +28,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
Ensure("/tmp/hakurei.1971/runtime/0", 0700).UpdatePermType(system.User, "/tmp/hakurei.1971/runtime/0", acl.Read, acl.Write, acl.Execute).
|
Ensure("/tmp/hakurei.1971/runtime/0", 0700).UpdatePermType(system.User, "/tmp/hakurei.1971/runtime/0", acl.Read, acl.Write, acl.Execute).
|
||||||
Ensure("/tmp/hakurei.1971/tmpdir", 0700).UpdatePermType(system.User, "/tmp/hakurei.1971/tmpdir", acl.Execute).
|
Ensure("/tmp/hakurei.1971/tmpdir", 0700).UpdatePermType(system.User, "/tmp/hakurei.1971/tmpdir", acl.Execute).
|
||||||
Ensure("/tmp/hakurei.1971/tmpdir/0", 01700).UpdatePermType(system.User, "/tmp/hakurei.1971/tmpdir/0", acl.Read, acl.Write, acl.Execute),
|
Ensure("/tmp/hakurei.1971/tmpdir/0", 01700).UpdatePermType(system.User, "/tmp/hakurei.1971/tmpdir/0", acl.Read, acl.Write, acl.Execute),
|
||||||
&hakurei.Params{
|
&container.Params{
|
||||||
Dir: "/home/chronos",
|
Dir: "/home/chronos",
|
||||||
Path: "/run/current-system/sw/bin/zsh",
|
Path: "/run/current-system/sw/bin/zsh",
|
||||||
Args: []string{"/run/current-system/sw/bin/zsh"},
|
Args: []string{"/run/current-system/sw/bin/zsh"},
|
||||||
@ -41,30 +41,30 @@ var testCasesPd = []sealTestCase{
|
|||||||
"XDG_SESSION_CLASS=user",
|
"XDG_SESSION_CLASS=user",
|
||||||
"XDG_SESSION_TYPE=tty",
|
"XDG_SESSION_TYPE=tty",
|
||||||
},
|
},
|
||||||
Ops: new(hakurei.Ops).
|
Ops: new(container.Ops).
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
Dev("/dev").Mqueue("/dev/mqueue").
|
Dev("/dev").Mqueue("/dev/mqueue").
|
||||||
Bind("/bin", "/bin", hakurei.BindWritable).
|
Bind("/bin", "/bin", container.BindWritable).
|
||||||
Bind("/boot", "/boot", hakurei.BindWritable).
|
Bind("/boot", "/boot", container.BindWritable).
|
||||||
Bind("/home", "/home", hakurei.BindWritable).
|
Bind("/home", "/home", container.BindWritable).
|
||||||
Bind("/lib", "/lib", hakurei.BindWritable).
|
Bind("/lib", "/lib", container.BindWritable).
|
||||||
Bind("/lib64", "/lib64", hakurei.BindWritable).
|
Bind("/lib64", "/lib64", container.BindWritable).
|
||||||
Bind("/nix", "/nix", hakurei.BindWritable).
|
Bind("/nix", "/nix", container.BindWritable).
|
||||||
Bind("/root", "/root", hakurei.BindWritable).
|
Bind("/root", "/root", container.BindWritable).
|
||||||
Bind("/run", "/run", hakurei.BindWritable).
|
Bind("/run", "/run", container.BindWritable).
|
||||||
Bind("/srv", "/srv", hakurei.BindWritable).
|
Bind("/srv", "/srv", container.BindWritable).
|
||||||
Bind("/sys", "/sys", hakurei.BindWritable).
|
Bind("/sys", "/sys", container.BindWritable).
|
||||||
Bind("/usr", "/usr", hakurei.BindWritable).
|
Bind("/usr", "/usr", container.BindWritable).
|
||||||
Bind("/var", "/var", hakurei.BindWritable).
|
Bind("/var", "/var", container.BindWritable).
|
||||||
Bind("/dev/kvm", "/dev/kvm", hakurei.BindWritable|hakurei.BindDevice|hakurei.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
Tmpfs("/run/dbus", 8192, 0755).
|
Tmpfs("/run/dbus", 8192, 0755).
|
||||||
Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac").
|
Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac").
|
||||||
Tmpfs("/run/user", 4096, 0755).
|
Tmpfs("/run/user", 4096, 0755).
|
||||||
Bind("/tmp/hakurei.1971/runtime/0", "/run/user/65534", hakurei.BindWritable).
|
Bind("/tmp/hakurei.1971/runtime/0", "/run/user/65534", container.BindWritable).
|
||||||
Bind("/tmp/hakurei.1971/tmpdir/0", "/tmp", hakurei.BindWritable).
|
Bind("/tmp/hakurei.1971/tmpdir/0", "/tmp", container.BindWritable).
|
||||||
Bind("/home/chronos", "/home/chronos", hakurei.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/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
||||||
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
||||||
Tmpfs("/var/run/nscd", 8192, 0755),
|
Tmpfs("/var/run/nscd", 8192, 0755),
|
||||||
@ -166,7 +166,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
}).
|
}).
|
||||||
UpdatePerm("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/bus", acl.Read, acl.Write).
|
UpdatePerm("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/bus", acl.Read, acl.Write).
|
||||||
UpdatePerm("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", acl.Read, acl.Write),
|
UpdatePerm("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", acl.Read, acl.Write),
|
||||||
&hakurei.Params{
|
&container.Params{
|
||||||
Dir: "/home/chronos",
|
Dir: "/home/chronos",
|
||||||
Path: "/run/current-system/sw/bin/zsh",
|
Path: "/run/current-system/sw/bin/zsh",
|
||||||
Args: []string{"zsh", "-c", "exec chromium "},
|
Args: []string{"zsh", "-c", "exec chromium "},
|
||||||
@ -184,31 +184,31 @@ var testCasesPd = []sealTestCase{
|
|||||||
"XDG_SESSION_CLASS=user",
|
"XDG_SESSION_CLASS=user",
|
||||||
"XDG_SESSION_TYPE=tty",
|
"XDG_SESSION_TYPE=tty",
|
||||||
},
|
},
|
||||||
Ops: new(hakurei.Ops).
|
Ops: new(container.Ops).
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 4096, 0755).
|
Tmpfs(hst.Tmp, 4096, 0755).
|
||||||
Dev("/dev").Mqueue("/dev/mqueue").
|
Dev("/dev").Mqueue("/dev/mqueue").
|
||||||
Bind("/bin", "/bin", hakurei.BindWritable).
|
Bind("/bin", "/bin", container.BindWritable).
|
||||||
Bind("/boot", "/boot", hakurei.BindWritable).
|
Bind("/boot", "/boot", container.BindWritable).
|
||||||
Bind("/home", "/home", hakurei.BindWritable).
|
Bind("/home", "/home", container.BindWritable).
|
||||||
Bind("/lib", "/lib", hakurei.BindWritable).
|
Bind("/lib", "/lib", container.BindWritable).
|
||||||
Bind("/lib64", "/lib64", hakurei.BindWritable).
|
Bind("/lib64", "/lib64", container.BindWritable).
|
||||||
Bind("/nix", "/nix", hakurei.BindWritable).
|
Bind("/nix", "/nix", container.BindWritable).
|
||||||
Bind("/root", "/root", hakurei.BindWritable).
|
Bind("/root", "/root", container.BindWritable).
|
||||||
Bind("/run", "/run", hakurei.BindWritable).
|
Bind("/run", "/run", container.BindWritable).
|
||||||
Bind("/srv", "/srv", hakurei.BindWritable).
|
Bind("/srv", "/srv", container.BindWritable).
|
||||||
Bind("/sys", "/sys", hakurei.BindWritable).
|
Bind("/sys", "/sys", container.BindWritable).
|
||||||
Bind("/usr", "/usr", hakurei.BindWritable).
|
Bind("/usr", "/usr", container.BindWritable).
|
||||||
Bind("/var", "/var", hakurei.BindWritable).
|
Bind("/var", "/var", container.BindWritable).
|
||||||
Bind("/dev/dri", "/dev/dri", hakurei.BindWritable|hakurei.BindDevice|hakurei.BindOptional).
|
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Bind("/dev/kvm", "/dev/kvm", hakurei.BindWritable|hakurei.BindDevice|hakurei.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
Tmpfs("/run/dbus", 8192, 0755).
|
Tmpfs("/run/dbus", 8192, 0755).
|
||||||
Etc("/etc", "ebf083d1b175911782d413369b64ce7c").
|
Etc("/etc", "ebf083d1b175911782d413369b64ce7c").
|
||||||
Tmpfs("/run/user", 4096, 0755).
|
Tmpfs("/run/user", 4096, 0755).
|
||||||
Bind("/tmp/hakurei.1971/runtime/9", "/run/user/65534", hakurei.BindWritable).
|
Bind("/tmp/hakurei.1971/runtime/9", "/run/user/65534", container.BindWritable).
|
||||||
Bind("/tmp/hakurei.1971/tmpdir/9", "/tmp", hakurei.BindWritable).
|
Bind("/tmp/hakurei.1971/tmpdir/9", "/tmp", container.BindWritable).
|
||||||
Bind("/home/chronos", "/home/chronos", hakurei.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/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
||||||
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
Place("/etc/group", []byte("hakurei:x:65534:\n")).
|
||||||
Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/65534/wayland-0", 0).
|
Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/wayland", "/run/user/65534/wayland-0", 0).
|
||||||
|
@ -7,9 +7,9 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
|
||||||
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
||||||
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app/internal/setuid"
|
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app/internal/setuid"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/sys"
|
"git.gensokyo.uk/security/hakurei/internal/sys"
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
@ -21,7 +21,7 @@ type sealTestCase struct {
|
|||||||
config *hst.Config
|
config *hst.Config
|
||||||
id app.ID
|
id app.ID
|
||||||
wantSys *system.I
|
wantSys *system.I
|
||||||
wantContainer *hakurei.Params
|
wantContainer *container.Params
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApp(t *testing.T) {
|
func TestApp(t *testing.T) {
|
||||||
@ -32,7 +32,7 @@ func TestApp(t *testing.T) {
|
|||||||
a := setuid.NewWithID(tc.id, tc.os)
|
a := setuid.NewWithID(tc.id, tc.os)
|
||||||
var (
|
var (
|
||||||
gotSys *system.I
|
gotSys *system.I
|
||||||
gotContainer *hakurei.Params
|
gotContainer *container.Params
|
||||||
)
|
)
|
||||||
if !t.Run("seal", func(t *testing.T) {
|
if !t.Run("seal", func(t *testing.T) {
|
||||||
if sa, err := a.Seal(tc.config); err != nil {
|
if sa, err := a.Seal(tc.config); err != nil {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package setuid
|
package setuid
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gensokyo.uk/security/hakurei"
|
|
||||||
. "git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
. "git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/sys"
|
"git.gensokyo.uk/security/hakurei/internal/sys"
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
)
|
)
|
||||||
@ -14,7 +14,7 @@ func NewWithID(id ID, os sys.State) App {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
func AppIParams(a App, sa SealedApp) (*system.I, *hakurei.Params) {
|
func AppIParams(a App, sa SealedApp) (*system.I, *container.Params) {
|
||||||
v := a.(*app)
|
v := a.(*app)
|
||||||
seal := sa.(*outcome)
|
seal := sa.(*outcome)
|
||||||
if v.outcome != seal || v.id != seal.id {
|
if v.outcome != seal || v.id != seal.id {
|
||||||
|
@ -12,9 +12,9 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
|
||||||
. "git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
. "git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
||||||
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/state"
|
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/state"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
@ -94,7 +94,7 @@ func (seal *outcome) Run(rs *RunState) error {
|
|||||||
cmd.Cancel = func() error { return cmd.Process.Signal(syscall.SIGCONT) }
|
cmd.Cancel = func() error { return cmd.Process.Signal(syscall.SIGCONT) }
|
||||||
|
|
||||||
var e *gob.Encoder
|
var e *gob.Encoder
|
||||||
if fd, encoder, err := hakurei.Setup(&cmd.ExtraFiles); err != nil {
|
if fd, encoder, err := container.Setup(&cmd.ExtraFiles); err != nil {
|
||||||
return hlog.WrapErrSuffix(err,
|
return hlog.WrapErrSuffix(err,
|
||||||
"cannot create shim setup pipe:")
|
"cannot create shim setup pipe:")
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,9 +16,9 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
|
||||||
. "git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
. "git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app"
|
||||||
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app/instance/common"
|
"git.gensokyo.uk/security/hakurei/cmd/hakurei/internal/app/instance/common"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
@ -80,7 +80,7 @@ type outcome struct {
|
|||||||
sys *system.I
|
sys *system.I
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
container *hakurei.Params
|
container *container.Params
|
||||||
env map[string]string
|
env map[string]string
|
||||||
sync *os.File
|
sync *os.File
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
seal.sys.Ensure(runtimeDirInst, 0700)
|
seal.sys.Ensure(runtimeDirInst, 0700)
|
||||||
seal.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read, acl.Write, acl.Execute)
|
seal.sys.UpdatePermType(system.User, runtimeDirInst, acl.Read, acl.Write, acl.Execute)
|
||||||
seal.container.Tmpfs("/run/user", 1<<12, 0755)
|
seal.container.Tmpfs("/run/user", 1<<12, 0755)
|
||||||
seal.container.Bind(runtimeDirInst, innerRuntimeDir, hakurei.BindWritable)
|
seal.container.Bind(runtimeDirInst, innerRuntimeDir, container.BindWritable)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -345,7 +345,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
seal.sys.Ensure(tmpdirInst, 01700)
|
seal.sys.Ensure(tmpdirInst, 01700)
|
||||||
seal.sys.UpdatePermType(system.User, tmpdirInst, acl.Read, acl.Write, acl.Execute)
|
seal.sys.UpdatePermType(system.User, tmpdirInst, acl.Read, acl.Write, acl.Execute)
|
||||||
// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp
|
// mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp
|
||||||
seal.container.Bind(tmpdirInst, "/tmp", hakurei.BindWritable)
|
seal.container.Bind(tmpdirInst, "/tmp", container.BindWritable)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -357,7 +357,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
if seal.user.username != "" {
|
if seal.user.username != "" {
|
||||||
username = seal.user.username
|
username = seal.user.username
|
||||||
}
|
}
|
||||||
seal.container.Bind(seal.user.data, homeDir, hakurei.BindWritable)
|
seal.container.Bind(seal.user.data, homeDir, container.BindWritable)
|
||||||
seal.container.Dir = homeDir
|
seal.container.Dir = homeDir
|
||||||
seal.env["HOME"] = homeDir
|
seal.env["HOME"] = homeDir
|
||||||
seal.env["USER"] = username
|
seal.env["USER"] = username
|
||||||
|
@ -10,10 +10,10 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -74,7 +74,7 @@ type shimParams struct {
|
|||||||
Monitor int
|
Monitor int
|
||||||
|
|
||||||
// finalised container params
|
// finalised container params
|
||||||
Container *hakurei.Params
|
Container *container.Params
|
||||||
// path to outer home directory
|
// path to outer home directory
|
||||||
Home string
|
Home string
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ type shimParams struct {
|
|||||||
func ShimMain() {
|
func ShimMain() {
|
||||||
hlog.Prepare("shim")
|
hlog.Prepare("shim")
|
||||||
|
|
||||||
if err := hakurei.SetDumpable(hakurei.SUID_DUMP_DISABLE); err != nil {
|
if err := container.SetDumpable(container.SUID_DUMP_DISABLE); err != nil {
|
||||||
log.Fatalf("cannot set SUID_DUMP_DISABLE: %s", err)
|
log.Fatalf("cannot set SUID_DUMP_DISABLE: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,11 +94,11 @@ func ShimMain() {
|
|||||||
params shimParams
|
params shimParams
|
||||||
closeSetup func() error
|
closeSetup func() error
|
||||||
)
|
)
|
||||||
if f, err := hakurei.Receive(shimEnv, ¶ms, nil); err != nil {
|
if f, err := container.Receive(shimEnv, ¶ms, nil); err != nil {
|
||||||
if errors.Is(err, hakurei.ErrInvalid) {
|
if errors.Is(err, container.ErrInvalid) {
|
||||||
log.Fatal("invalid config descriptor")
|
log.Fatal("invalid config descriptor")
|
||||||
}
|
}
|
||||||
if errors.Is(err, hakurei.ErrNotSet) {
|
if errors.Is(err, container.ErrNotSet) {
|
||||||
log.Fatal("HAKUREI_SHIM not set")
|
log.Fatal("HAKUREI_SHIM not set")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,17 +149,17 @@ func ShimMain() {
|
|||||||
}
|
}
|
||||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
defer stop() // unreachable
|
defer stop() // unreachable
|
||||||
container := hakurei.New(ctx, name)
|
z := container.New(ctx, name)
|
||||||
container.Params = *params.Container
|
z.Params = *params.Container
|
||||||
container.Stdin, container.Stdout, container.Stderr = os.Stdin, os.Stdout, os.Stderr
|
z.Stdin, z.Stdout, z.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
container.Cancel = func(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) }
|
z.Cancel = func(cmd *exec.Cmd) error { return cmd.Process.Signal(os.Interrupt) }
|
||||||
container.WaitDelay = 2 * time.Second
|
z.WaitDelay = 2 * time.Second
|
||||||
|
|
||||||
if err := container.Start(); err != nil {
|
if err := z.Start(); err != nil {
|
||||||
hlog.PrintBaseError(err, "cannot start container:")
|
hlog.PrintBaseError(err, "cannot start container:")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if err := container.Serve(); err != nil {
|
if err := z.Serve(); err != nil {
|
||||||
hlog.PrintBaseError(err, "cannot configure container:")
|
hlog.PrintBaseError(err, "cannot configure container:")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ func ShimMain() {
|
|||||||
log.Fatalf("cannot load syscall filter: %v", err)
|
log.Fatalf("cannot load syscall filter: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := container.Wait(); err != nil {
|
if err := z.Wait(); err != nil {
|
||||||
var exitError *exec.ExitError
|
var exitError *exec.ExitError
|
||||||
if !errors.As(err, &exitError) {
|
if !errors.As(err, &exitError) {
|
||||||
if errors.Is(err, context.Canceled) {
|
if errors.Is(err, context.Canceled) {
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/sys"
|
"git.gensokyo.uk/security/hakurei/internal/sys"
|
||||||
@ -28,9 +28,9 @@ var std sys.State = new(sys.Std)
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// early init path, skips root check and duplicate PR_SET_DUMPABLE
|
// early init path, skips root check and duplicate PR_SET_DUMPABLE
|
||||||
hakurei.TryArgv0(hlog.Output{}, hlog.Prepare, internal.InstallOutput)
|
container.TryArgv0(hlog.Output{}, hlog.Prepare, internal.InstallOutput)
|
||||||
|
|
||||||
if err := hakurei.SetDumpable(hakurei.SUID_DUMP_DISABLE); err != nil {
|
if err := container.SetDumpable(container.SUID_DUMP_DISABLE); err != nil {
|
||||||
log.Printf("cannot set SUID_DUMP_DISABLE: %s", err)
|
log.Printf("cannot set SUID_DUMP_DISABLE: %s", err)
|
||||||
// not fatal: this program runs as the privileged user
|
// not fatal: this program runs as the privileged user
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
"git.gensokyo.uk/security/hakurei/system/dbus"
|
"git.gensokyo.uk/security/hakurei/system/dbus"
|
||||||
)
|
)
|
||||||
|
@ -5,9 +5,9 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func withNixDaemon(
|
func withNixDaemon(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Package hakurei implements unprivileged Linux containers with built-in support for syscall filtering.
|
// Package container implements unprivileged Linux containers with built-in support for syscall filtering.
|
||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -14,7 +14,7 @@ import (
|
|||||||
. "syscall"
|
. "syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei_test
|
package container_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -12,13 +12,13 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/vfs"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
"git.gensokyo.uk/security/hakurei/ldd"
|
"git.gensokyo.uk/security/hakurei/ldd"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
"git.gensokyo.uk/security/hakurei/vfs"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -29,10 +29,10 @@ const (
|
|||||||
func TestContainer(t *testing.T) {
|
func TestContainer(t *testing.T) {
|
||||||
{
|
{
|
||||||
oldVerbose := hlog.Load()
|
oldVerbose := hlog.Load()
|
||||||
oldOutput := hakurei.GetOutput()
|
oldOutput := container.GetOutput()
|
||||||
internal.InstallOutput(true)
|
internal.InstallOutput(true)
|
||||||
t.Cleanup(func() { hlog.Store(oldVerbose) })
|
t.Cleanup(func() { hlog.Store(oldVerbose) })
|
||||||
t.Cleanup(func() { hakurei.SetOutput(oldOutput) })
|
t.Cleanup(func() { container.SetOutput(oldOutput) })
|
||||||
}
|
}
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
@ -40,7 +40,7 @@ func TestContainer(t *testing.T) {
|
|||||||
filter bool
|
filter bool
|
||||||
session bool
|
session bool
|
||||||
net bool
|
net bool
|
||||||
ops *hakurei.Ops
|
ops *container.Ops
|
||||||
mnt []*vfs.MountInfoEntry
|
mnt []*vfs.MountInfoEntry
|
||||||
host string
|
host string
|
||||||
rules []seccomp.NativeRule
|
rules []seccomp.NativeRule
|
||||||
@ -48,28 +48,28 @@ func TestContainer(t *testing.T) {
|
|||||||
presets seccomp.FilterPreset
|
presets seccomp.FilterPreset
|
||||||
}{
|
}{
|
||||||
{"minimal", true, false, false,
|
{"minimal", true, false, false,
|
||||||
new(hakurei.Ops), nil, "test-minimal",
|
new(container.Ops), nil, "test-minimal",
|
||||||
nil, 0, seccomp.PresetStrict},
|
nil, 0, seccomp.PresetStrict},
|
||||||
{"allow", true, true, true,
|
{"allow", true, true, true,
|
||||||
new(hakurei.Ops), nil, "test-minimal",
|
new(container.Ops), nil, "test-minimal",
|
||||||
nil, 0, seccomp.PresetExt | seccomp.PresetDenyDevel},
|
nil, 0, seccomp.PresetExt | seccomp.PresetDenyDevel},
|
||||||
{"no filter", false, true, true,
|
{"no filter", false, true, true,
|
||||||
new(hakurei.Ops), nil, "test-no-filter",
|
new(container.Ops), nil, "test-no-filter",
|
||||||
nil, 0, seccomp.PresetExt},
|
nil, 0, seccomp.PresetExt},
|
||||||
{"custom rules", true, true, true,
|
{"custom rules", true, true, true,
|
||||||
new(hakurei.Ops), nil, "test-no-filter",
|
new(container.Ops), nil, "test-no-filter",
|
||||||
[]seccomp.NativeRule{
|
[]seccomp.NativeRule{
|
||||||
{seccomp.ScmpSyscall(syscall.SYS_SETUID), seccomp.ScmpErrno(syscall.EPERM), nil},
|
{seccomp.ScmpSyscall(syscall.SYS_SETUID), seccomp.ScmpErrno(syscall.EPERM), nil},
|
||||||
}, 0, seccomp.PresetExt},
|
}, 0, seccomp.PresetExt},
|
||||||
{"tmpfs", true, false, false,
|
{"tmpfs", true, false, false,
|
||||||
new(hakurei.Ops).
|
new(container.Ops).
|
||||||
Tmpfs(hst.Tmp, 0, 0755),
|
Tmpfs(hst.Tmp, 0, 0755),
|
||||||
[]*vfs.MountInfoEntry{
|
[]*vfs.MountInfoEntry{
|
||||||
e("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "tmpfs", ignore),
|
e("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "tmpfs", ignore),
|
||||||
}, "test-tmpfs",
|
}, "test-tmpfs",
|
||||||
nil, 0, seccomp.PresetStrict},
|
nil, 0, seccomp.PresetStrict},
|
||||||
{"dev", true, true /* go test output is not a tty */, false,
|
{"dev", true, true /* go test output is not a tty */, false,
|
||||||
new(hakurei.Ops).
|
new(container.Ops).
|
||||||
Dev("/dev").
|
Dev("/dev").
|
||||||
Mqueue("/dev/mqueue"),
|
Mqueue("/dev/mqueue"),
|
||||||
[]*vfs.MountInfoEntry{
|
[]*vfs.MountInfoEntry{
|
||||||
@ -91,34 +91,34 @@ func TestContainer(t *testing.T) {
|
|||||||
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
|
ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
container := hakurei.New(ctx, "/usr/bin/sandbox.test", "-test.v",
|
c := container.New(ctx, "/usr/bin/sandbox.test", "-test.v",
|
||||||
"-test.run=TestHelperCheckContainer", "--", "check", tc.host)
|
"-test.run=TestHelperCheckContainer", "--", "check", tc.host)
|
||||||
container.Uid = 1000
|
c.Uid = 1000
|
||||||
container.Gid = 100
|
c.Gid = 100
|
||||||
container.Hostname = tc.host
|
c.Hostname = tc.host
|
||||||
container.CommandContext = commandContext
|
c.CommandContext = commandContext
|
||||||
container.Stdout, container.Stderr = os.Stdout, os.Stderr
|
c.Stdout, c.Stderr = os.Stdout, os.Stderr
|
||||||
container.Ops = tc.ops
|
c.Ops = tc.ops
|
||||||
container.SeccompRules = tc.rules
|
c.SeccompRules = tc.rules
|
||||||
container.SeccompFlags = tc.flags | seccomp.AllowMultiarch
|
c.SeccompFlags = tc.flags | seccomp.AllowMultiarch
|
||||||
container.SeccompPresets = tc.presets
|
c.SeccompPresets = tc.presets
|
||||||
container.SeccompDisable = !tc.filter
|
c.SeccompDisable = !tc.filter
|
||||||
container.RetainSession = tc.session
|
c.RetainSession = tc.session
|
||||||
container.HostNet = tc.net
|
c.HostNet = tc.net
|
||||||
if container.Args[5] == "" {
|
if c.Args[5] == "" {
|
||||||
if name, err := os.Hostname(); err != nil {
|
if name, err := os.Hostname(); err != nil {
|
||||||
t.Fatalf("cannot get hostname: %v", err)
|
t.Fatalf("cannot get hostname: %v", err)
|
||||||
} else {
|
} else {
|
||||||
container.Args[5] = name
|
c.Args[5] = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container.
|
c.
|
||||||
Tmpfs("/tmp", 0, 0755).
|
Tmpfs("/tmp", 0, 0755).
|
||||||
Bind(os.Args[0], os.Args[0], 0).
|
Bind(os.Args[0], os.Args[0], 0).
|
||||||
Mkdir("/usr/bin", 0755).
|
Mkdir("/usr/bin", 0755).
|
||||||
Link(os.Args[0], "/usr/bin/sandbox.test").
|
Link(os.Args[0], "/usr/bin/sandbox.test").
|
||||||
Place("/etc/hostname", []byte(container.Args[5]))
|
Place("/etc/hostname", []byte(c.Args[5]))
|
||||||
// in case test has cgo enabled
|
// in case test has cgo enabled
|
||||||
var libPaths []string
|
var libPaths []string
|
||||||
if entries, err := ldd.ExecFilter(ctx,
|
if entries, err := ldd.ExecFilter(ctx,
|
||||||
@ -131,10 +131,10 @@ func TestContainer(t *testing.T) {
|
|||||||
libPaths = ldd.Path(entries)
|
libPaths = ldd.Path(entries)
|
||||||
}
|
}
|
||||||
for _, name := range libPaths {
|
for _, name := range libPaths {
|
||||||
container.Bind(name, name, 0)
|
c.Bind(name, name, 0)
|
||||||
}
|
}
|
||||||
// needs /proc to check mountinfo
|
// needs /proc to check mountinfo
|
||||||
container.Proc("/proc")
|
c.Proc("/proc")
|
||||||
|
|
||||||
mnt := make([]*vfs.MountInfoEntry, 0, 3+len(libPaths))
|
mnt := make([]*vfs.MountInfoEntry, 0, 3+len(libPaths))
|
||||||
mnt = append(mnt, e("/sysroot", "/", "rw,nosuid,nodev,relatime", "tmpfs", "rootfs", ignore))
|
mnt = append(mnt, e("/sysroot", "/", "rw,nosuid,nodev,relatime", "tmpfs", "rootfs", ignore))
|
||||||
@ -152,16 +152,16 @@ func TestContainer(t *testing.T) {
|
|||||||
if err := gob.NewEncoder(want).Encode(mnt); err != nil {
|
if err := gob.NewEncoder(want).Encode(mnt); err != nil {
|
||||||
t.Fatalf("cannot serialise expected mount points: %v", err)
|
t.Fatalf("cannot serialise expected mount points: %v", err)
|
||||||
}
|
}
|
||||||
container.Stdin = want
|
c.Stdin = want
|
||||||
|
|
||||||
if err := container.Start(); err != nil {
|
if err := c.Start(); err != nil {
|
||||||
hlog.PrintBaseError(err, "start:")
|
hlog.PrintBaseError(err, "start:")
|
||||||
t.Fatalf("cannot start container: %v", err)
|
t.Fatalf("cannot start container: %v", err)
|
||||||
} else if err = container.Serve(); err != nil {
|
} else if err = c.Serve(); err != nil {
|
||||||
hlog.PrintBaseError(err, "serve:")
|
hlog.PrintBaseError(err, "serve:")
|
||||||
t.Errorf("cannot serve setup params: %v", err)
|
t.Errorf("cannot serve setup params: %v", err)
|
||||||
}
|
}
|
||||||
if err := container.Wait(); err != nil {
|
if err := c.Wait(); err != nil {
|
||||||
hlog.PrintBaseError(err, "wait:")
|
hlog.PrintBaseError(err, "wait:")
|
||||||
t.Fatalf("wait: %v", err)
|
t.Fatalf("wait: %v", err)
|
||||||
}
|
}
|
||||||
@ -185,14 +185,14 @@ func e(root, target, vfsOptstr, fsType, source, fsOptstr string) *vfs.MountInfoE
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestContainerString(t *testing.T) {
|
func TestContainerString(t *testing.T) {
|
||||||
container := hakurei.New(t.Context(), "ldd", "/usr/bin/env")
|
c := container.New(t.Context(), "ldd", "/usr/bin/env")
|
||||||
container.SeccompFlags |= seccomp.AllowMultiarch
|
c.SeccompFlags |= seccomp.AllowMultiarch
|
||||||
container.SeccompRules = seccomp.Preset(
|
c.SeccompRules = seccomp.Preset(
|
||||||
seccomp.PresetExt|seccomp.PresetDenyNS|seccomp.PresetDenyTTY,
|
seccomp.PresetExt|seccomp.PresetDenyNS|seccomp.PresetDenyTTY,
|
||||||
container.SeccompFlags)
|
c.SeccompFlags)
|
||||||
container.SeccompPresets = seccomp.PresetStrict
|
c.SeccompPresets = seccomp.PresetStrict
|
||||||
want := `argv: ["ldd" "/usr/bin/env"], filter: true, rules: 65, flags: 0x1, presets: 0xf`
|
want := `argv: ["ldd" "/usr/bin/env"], filter: true, rules: 65, flags: 0x1, presets: 0xf`
|
||||||
if got := container.String(); got != want {
|
if got := c.String(); got != want {
|
||||||
t.Errorf("String: %s, want %s", got, want)
|
t.Errorf("String: %s, want %s", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,8 +201,8 @@ func TestHelperInit(t *testing.T) {
|
|||||||
if len(os.Args) != 5 || os.Args[4] != "init" {
|
if len(os.Args) != 5 || os.Args[4] != "init" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hakurei.SetOutput(hlog.Output{})
|
container.SetOutput(hlog.Output{})
|
||||||
hakurei.Init(hlog.Prepare, internal.InstallOutput)
|
container.Init(hlog.Prepare, internal.InstallOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHelperCheckContainer(t *testing.T) {
|
func TestHelperCheckContainer(t *testing.T) {
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
@ -1,15 +1,15 @@
|
|||||||
package hakurei_test
|
package container_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestExecutable(t *testing.T) {
|
func TestExecutable(t *testing.T) {
|
||||||
for i := 0; i < 16; i++ {
|
for i := 0; i < 16; i++ {
|
||||||
if got := hakurei.MustExecutable(); got != os.Args[0] {
|
if got := container.MustExecutable(); got != os.Args[0] {
|
||||||
t.Errorf("MustExecutable: %q, want %q",
|
t.Errorf("MustExecutable: %q, want %q",
|
||||||
got, os.Args[0])
|
got, os.Args[0])
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -13,7 +13,7 @@ import (
|
|||||||
. "syscall"
|
. "syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -7,7 +7,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
. "syscall"
|
. "syscall"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/vfs"
|
"git.gensokyo.uk/security/hakurei/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) error {
|
func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) error {
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
var msg Msg = new(DefaultMsg)
|
var msg Msg = new(DefaultMsg)
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/gob"
|
"encoding/gob"
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/vfs"
|
"git.gensokyo.uk/security/hakurei/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
@ -8,7 +8,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
. "git.gensokyo.uk/security/hakurei/seccomp"
|
. "git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestExport(t *testing.T) {
|
func TestExport(t *testing.T) {
|
@ -6,7 +6,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLibraryError(t *testing.T) {
|
func TestLibraryError(t *testing.T) {
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
@ -1,4 +1,4 @@
|
|||||||
package hakurei
|
package container
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
@ -3,7 +3,7 @@ package vfs_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/vfs"
|
"git.gensokyo.uk/security/hakurei/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUnmangle(t *testing.T) {
|
func TestUnmangle(t *testing.T) {
|
@ -12,7 +12,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/vfs"
|
"git.gensokyo.uk/security/hakurei/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMountInfo(t *testing.T) {
|
func TestMountInfo(t *testing.T) {
|
@ -8,7 +8,7 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei/vfs"
|
"git.gensokyo.uk/security/hakurei/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUnfold(t *testing.T) {
|
func TestUnfold(t *testing.T) {
|
@ -9,7 +9,7 @@ import (
|
|||||||
"slices"
|
"slices"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/helper/proc"
|
"git.gensokyo.uk/security/hakurei/helper/proc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -20,13 +20,13 @@ func New(
|
|||||||
wt io.WriterTo,
|
wt io.WriterTo,
|
||||||
stat bool,
|
stat bool,
|
||||||
argF func(argsFd, statFd int) []string,
|
argF func(argsFd, statFd int) []string,
|
||||||
cmdF func(container *hakurei.Container),
|
cmdF func(z *container.Container),
|
||||||
extraFiles []*os.File,
|
extraFiles []*os.File,
|
||||||
) Helper {
|
) Helper {
|
||||||
var args []string
|
var args []string
|
||||||
h := new(helperContainer)
|
h := new(helperContainer)
|
||||||
h.helperFiles, args = newHelperFiles(ctx, wt, stat, argF, extraFiles)
|
h.helperFiles, args = newHelperFiles(ctx, wt, stat, argF, extraFiles)
|
||||||
h.Container = hakurei.New(ctx, name, args...)
|
h.Container = container.New(ctx, name, args...)
|
||||||
h.WaitDelay = WaitDelay
|
h.WaitDelay = WaitDelay
|
||||||
if cmdF != nil {
|
if cmdF != nil {
|
||||||
cmdF(h.Container)
|
cmdF(h.Container)
|
||||||
@ -40,7 +40,7 @@ type helperContainer struct {
|
|||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
*helperFiles
|
*helperFiles
|
||||||
*hakurei.Container
|
*container.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *helperContainer) Start() error {
|
func (h *helperContainer) Start() error {
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/helper"
|
"git.gensokyo.uk/security/hakurei/helper"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
@ -34,15 +34,13 @@ func TestContainer(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("implementation compliance", func(t *testing.T) {
|
t.Run("implementation compliance", func(t *testing.T) {
|
||||||
testHelper(t, func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper {
|
testHelper(t, func(ctx context.Context, setOutput func(stdoutP, stderrP *io.Writer), stat bool) helper.Helper {
|
||||||
return helper.New(ctx, os.Args[0], argsWt, stat, argF, func(container *hakurei.Container) {
|
return helper.New(ctx, os.Args[0], argsWt, stat, argF, func(z *container.Container) {
|
||||||
setOutput(&container.Stdout, &container.Stderr)
|
setOutput(&z.Stdout, &z.Stderr)
|
||||||
container.CommandContext = func(ctx context.Context) (cmd *exec.Cmd) {
|
z.CommandContext = func(ctx context.Context) (cmd *exec.Cmd) {
|
||||||
return exec.CommandContext(ctx, os.Args[0], "-test.v",
|
return exec.CommandContext(ctx, os.Args[0], "-test.v",
|
||||||
"-test.run=TestHelperInit", "--", "init")
|
"-test.run=TestHelperInit", "--", "init")
|
||||||
}
|
}
|
||||||
container.Bind("/", "/", 0)
|
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev")
|
||||||
container.Proc("/proc")
|
|
||||||
container.Dev("/dev")
|
|
||||||
}, nil)
|
}, nil)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -52,6 +50,6 @@ func TestHelperInit(t *testing.T) {
|
|||||||
if len(os.Args) != 5 || os.Args[4] != "init" {
|
if len(os.Args) != 5 || os.Args[4] != "init" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hakurei.SetOutput(hlog.Output{})
|
container.SetOutput(hlog.Output{})
|
||||||
hakurei.Init(hlog.Prepare, func(bool) { internal.InstallOutput(false) })
|
container.Init(hlog.Prepare, func(bool) { internal.InstallOutput(false) })
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package hst
|
package hst
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package hst
|
package hst
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
"git.gensokyo.uk/security/hakurei/system/dbus"
|
"git.gensokyo.uk/security/hakurei/system/dbus"
|
||||||
)
|
)
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package internal
|
package internal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
"git.gensokyo.uk/security/hakurei/system"
|
"git.gensokyo.uk/security/hakurei/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
func InstallOutput(verbose bool) {
|
func InstallOutput(verbose bool) {
|
||||||
hlog.Store(verbose)
|
hlog.Store(verbose)
|
||||||
hakurei.SetOutput(hlog.Output{})
|
container.SetOutput(hlog.Output{})
|
||||||
system.SetOutput(hlog.Output{})
|
system.SetOutput(hlog.Output{})
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/hst"
|
"git.gensokyo.uk/security/hakurei/hst"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
@ -36,7 +36,7 @@ func (s *Std) Getgid() int { return os.Getgid()
|
|||||||
func (s *Std) LookupEnv(key string) (string, bool) { return os.LookupEnv(key) }
|
func (s *Std) LookupEnv(key string) (string, bool) { return os.LookupEnv(key) }
|
||||||
func (s *Std) TempDir() string { return os.TempDir() }
|
func (s *Std) TempDir() string { return os.TempDir() }
|
||||||
func (s *Std) LookPath(file string) (string, error) { return exec.LookPath(file) }
|
func (s *Std) LookPath(file string) (string, error) { return exec.LookPath(file) }
|
||||||
func (s *Std) MustExecutable() string { return hakurei.MustExecutable() }
|
func (s *Std) MustExecutable() string { return container.MustExecutable() }
|
||||||
func (s *Std) LookupGroup(name string) (*user.Group, error) { return user.LookupGroup(name) }
|
func (s *Std) LookupGroup(name string) (*user.Group, error) { return user.LookupGroup(name) }
|
||||||
func (s *Std) ReadDir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
|
func (s *Std) ReadDir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
|
||||||
func (s *Std) Stat(name string) (fs.FileInfo, error) { return os.Stat(name) }
|
func (s *Std) Stat(name string) (fs.FileInfo, error) { return os.Stat(name) }
|
||||||
|
26
ldd/exec.go
26
ldd/exec.go
@ -8,8 +8,8 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
const lddTimeout = 2 * time.Second
|
const lddTimeout = 2 * time.Second
|
||||||
@ -27,24 +27,24 @@ func ExecFilter(ctx context.Context,
|
|||||||
p string) ([]*Entry, error) {
|
p string) ([]*Entry, error) {
|
||||||
c, cancel := context.WithTimeout(ctx, lddTimeout)
|
c, cancel := context.WithTimeout(ctx, lddTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
container := hakurei.New(c, "ldd", p)
|
z := container.New(c, "ldd", p)
|
||||||
container.CommandContext = commandContext
|
z.CommandContext = commandContext
|
||||||
container.Hostname = "hakurei-ldd"
|
z.Hostname = "hakurei-ldd"
|
||||||
container.SeccompFlags |= seccomp.AllowMultiarch
|
z.SeccompFlags |= seccomp.AllowMultiarch
|
||||||
container.SeccompPresets |= seccomp.PresetStrict
|
z.SeccompPresets |= seccomp.PresetStrict
|
||||||
stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
|
stdout, stderr := new(bytes.Buffer), new(bytes.Buffer)
|
||||||
container.Stdout = stdout
|
z.Stdout = stdout
|
||||||
container.Stderr = stderr
|
z.Stderr = stderr
|
||||||
container.Bind("/", "/", 0).Proc("/proc").Dev("/dev")
|
z.Bind("/", "/", 0).Proc("/proc").Dev("/dev")
|
||||||
|
|
||||||
if err := container.Start(); err != nil {
|
if err := z.Start(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer func() { _, _ = io.Copy(os.Stderr, stderr) }()
|
defer func() { _, _ = io.Copy(os.Stderr, stderr) }()
|
||||||
if err := container.Serve(); err != nil {
|
if err := z.Serve(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := container.Wait(); err != nil {
|
if err := z.Wait(); err != nil {
|
||||||
m := stderr.Bytes()
|
m := stderr.Bytes()
|
||||||
if bytes.Contains(m, append([]byte(p+": "), msgStatic...)) ||
|
if bytes.Contains(m, append([]byte(p+": "), msgStatic...)) ||
|
||||||
bytes.Contains(m, msgStaticGlibc) {
|
bytes.Contains(m, msgStaticGlibc) {
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
"git.gensokyo.uk/security/hakurei/helper"
|
"git.gensokyo.uk/security/hakurei/helper"
|
||||||
"git.gensokyo.uk/security/hakurei/internal"
|
"git.gensokyo.uk/security/hakurei/internal"
|
||||||
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
"git.gensokyo.uk/security/hakurei/internal/hlog"
|
||||||
@ -134,11 +134,11 @@ func testProxyFinaliseStartWaitCloseString(t *testing.T, useSandbox bool) {
|
|||||||
}
|
}
|
||||||
p.CmdF = func(v any) {
|
p.CmdF = func(v any) {
|
||||||
if useSandbox {
|
if useSandbox {
|
||||||
container := v.(*hakurei.Container)
|
z := v.(*container.Container)
|
||||||
if container.Args[0] != dbus.ProxyName {
|
if z.Args[0] != dbus.ProxyName {
|
||||||
panic(fmt.Sprintf("unexpected argv0 %q", os.Args[0]))
|
panic(fmt.Sprintf("unexpected argv0 %q", os.Args[0]))
|
||||||
}
|
}
|
||||||
container.Args = append([]string{os.Args[0], "-test.run=TestHelperStub", "--"}, container.Args[1:]...)
|
z.Args = append([]string{os.Args[0], "-test.run=TestHelperStub", "--"}, z.Args[1:]...)
|
||||||
} else {
|
} else {
|
||||||
cmd := v.(*exec.Cmd)
|
cmd := v.(*exec.Cmd)
|
||||||
if cmd.Args[0] != dbus.ProxyName {
|
if cmd.Args[0] != dbus.ProxyName {
|
||||||
@ -208,6 +208,6 @@ func TestHelperInit(t *testing.T) {
|
|||||||
if len(os.Args) != 5 || os.Args[4] != "init" {
|
if len(os.Args) != 5 || os.Args[4] != "init" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hakurei.SetOutput(hlog.Output{})
|
container.SetOutput(hlog.Output{})
|
||||||
hakurei.Init(hlog.Prepare, internal.InstallOutput)
|
container.Init(hlog.Prepare, internal.InstallOutput)
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
|
"git.gensokyo.uk/security/hakurei/container/seccomp"
|
||||||
"git.gensokyo.uk/security/hakurei/helper"
|
"git.gensokyo.uk/security/hakurei/helper"
|
||||||
"git.gensokyo.uk/security/hakurei/ldd"
|
"git.gensokyo.uk/security/hakurei/ldd"
|
||||||
"git.gensokyo.uk/security/hakurei/seccomp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Start starts and configures a D-Bus proxy process.
|
// Start starts and configures a D-Bus proxy process.
|
||||||
@ -65,22 +65,22 @@ func (p *Proxy) Start() error {
|
|||||||
p.helper = helper.New(
|
p.helper = helper.New(
|
||||||
ctx, toolPath,
|
ctx, toolPath,
|
||||||
p.final, true,
|
p.final, true,
|
||||||
argF, func(container *hakurei.Container) {
|
argF, func(z *container.Container) {
|
||||||
container.SeccompFlags |= seccomp.AllowMultiarch
|
z.SeccompFlags |= seccomp.AllowMultiarch
|
||||||
container.SeccompPresets |= seccomp.PresetStrict
|
z.SeccompPresets |= seccomp.PresetStrict
|
||||||
container.Hostname = "hakurei-dbus"
|
z.Hostname = "hakurei-dbus"
|
||||||
container.CommandContext = p.CommandContext
|
z.CommandContext = p.CommandContext
|
||||||
if p.output != nil {
|
if p.output != nil {
|
||||||
container.Stdout, container.Stderr = p.output, p.output
|
z.Stdout, z.Stderr = p.output, p.output
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.CmdF != nil {
|
if p.CmdF != nil {
|
||||||
p.CmdF(container)
|
p.CmdF(z)
|
||||||
}
|
}
|
||||||
|
|
||||||
// these lib paths are unpredictable, so mount them first so they cannot cover anything
|
// these lib paths are unpredictable, so mount them first so they cannot cover anything
|
||||||
for _, name := range libPaths {
|
for _, name := range libPaths {
|
||||||
container.Bind(name, name, 0)
|
z.Bind(name, name, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// upstream bus directories
|
// upstream bus directories
|
||||||
@ -101,7 +101,7 @@ func (p *Proxy) Start() error {
|
|||||||
slices.Sort(upstreamPaths)
|
slices.Sort(upstreamPaths)
|
||||||
upstreamPaths = slices.Compact(upstreamPaths)
|
upstreamPaths = slices.Compact(upstreamPaths)
|
||||||
for _, name := range upstreamPaths {
|
for _, name := range upstreamPaths {
|
||||||
container.Bind(name, name, 0)
|
z.Bind(name, name, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// parent directories of bind paths
|
// parent directories of bind paths
|
||||||
@ -115,12 +115,12 @@ func (p *Proxy) Start() error {
|
|||||||
slices.Sort(sockDirPaths)
|
slices.Sort(sockDirPaths)
|
||||||
sockDirPaths = slices.Compact(sockDirPaths)
|
sockDirPaths = slices.Compact(sockDirPaths)
|
||||||
for _, name := range sockDirPaths {
|
for _, name := range sockDirPaths {
|
||||||
container.Bind(name, name, hakurei.BindWritable)
|
z.Bind(name, name, container.BindWritable)
|
||||||
}
|
}
|
||||||
|
|
||||||
// xdg-dbus-proxy bin path
|
// xdg-dbus-proxy bin path
|
||||||
binPath := path.Dir(toolPath)
|
binPath := path.Dir(toolPath)
|
||||||
container.Bind(binPath, binPath, 0)
|
z.Bind(binPath, binPath, 0)
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"git.gensokyo.uk/security/hakurei"
|
"git.gensokyo.uk/security/hakurei/container"
|
||||||
)
|
)
|
||||||
|
|
||||||
var msg hakurei.Msg = new(hakurei.DefaultMsg)
|
var msg container.Msg = new(container.DefaultMsg)
|
||||||
|
|
||||||
func SetOutput(v hakurei.Msg) {
|
func SetOutput(v container.Msg) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
msg = new(hakurei.DefaultMsg)
|
msg = new(container.DefaultMsg)
|
||||||
} else {
|
} else {
|
||||||
msg = v
|
msg = v
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user