Compare commits
15 Commits
cb513bb1cd
...
f13dca184c
Author | SHA1 | Date | |
---|---|---|---|
f13dca184c | |||
3b8a3d3b00 | |||
c5d24979f5 | |||
1dc780bca7 | |||
ec33061c92 | |||
af0899de96 | |||
547a2adaa4 | |||
c02948e155 | |||
387b86bcdd | |||
4e85643865 | |||
987981df73 | |||
f14e7255be | |||
a8a79a8664 | |||
3ae0cec000 | |||
4e518f11d8 |
@ -73,20 +73,20 @@ jobs:
|
|||||||
path: result/*
|
path: result/*
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
planterette:
|
hpkg:
|
||||||
name: Planterette
|
name: Hpkg
|
||||||
runs-on: nix
|
runs-on: nix
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run NixOS test
|
- name: Run NixOS test
|
||||||
run: nix build --out-link "result" --print-out-paths --print-build-logs .#checks.x86_64-linux.planterette
|
run: nix build --out-link "result" --print-out-paths --print-build-logs .#checks.x86_64-linux.hpkg
|
||||||
|
|
||||||
- name: Upload test output
|
- name: Upload test output
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: "planterette-vm-output"
|
name: "hpkg-vm-output"
|
||||||
path: result/*
|
path: result/*
|
||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ jobs:
|
|||||||
- race
|
- race
|
||||||
- sandbox
|
- sandbox
|
||||||
- sandbox-race
|
- sandbox-race
|
||||||
- planterette
|
- hpkg
|
||||||
runs-on: nix
|
runs-on: nix
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
Hakurei is a tool for running sandboxed graphical applications as dedicated subordinate users on the Linux kernel.
|
Hakurei is a tool for running sandboxed graphical applications as dedicated subordinate users on the Linux kernel.
|
||||||
It also implements [planterette (WIP)](cmd/planterette), a self-contained Android-like package manager with modern security features.
|
It implements the application container of [planterette (WIP)](https://git.gensokyo.uk/security/planterette),
|
||||||
|
a self-contained Android-like package manager with modern security features.
|
||||||
|
|
||||||
## NixOS Module usage
|
## NixOS Module usage
|
||||||
|
|
||||||
|
@ -104,6 +104,10 @@ func printShowInstance(
|
|||||||
}
|
}
|
||||||
t.Printf(" Flags:\t%s\n", strings.Join(flags, " "))
|
t.Printf(" Flags:\t%s\n", strings.Join(flags, " "))
|
||||||
|
|
||||||
|
if container.AutoRoot != "" {
|
||||||
|
t.Printf(" Root:\t%s (%d)\n", container.AutoRoot, container.RootFlags)
|
||||||
|
}
|
||||||
|
|
||||||
etc := container.Etc
|
etc := container.Etc
|
||||||
if etc == "" {
|
if etc == "" {
|
||||||
etc = "/etc"
|
etc = "/etc"
|
||||||
|
@ -42,6 +42,7 @@ func Test_printShowInstance(t *testing.T) {
|
|||||||
Data: /var/lib/hakurei/u0/org.chromium.Chromium
|
Data: /var/lib/hakurei/u0/org.chromium.Chromium
|
||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Flags: userns devel net device tty mapuid autoetc
|
Flags: userns devel net device tty mapuid autoetc
|
||||||
|
Root: /var/lib/hakurei/base/org.debian (2)
|
||||||
Etc: /etc
|
Etc: /etc
|
||||||
Cover: /var/run/nscd
|
Cover: /var/run/nscd
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
@ -121,6 +122,7 @@ App
|
|||||||
Data: /var/lib/hakurei/u0/org.chromium.Chromium
|
Data: /var/lib/hakurei/u0/org.chromium.Chromium
|
||||||
Hostname: localhost
|
Hostname: localhost
|
||||||
Flags: userns devel net device tty mapuid autoetc
|
Flags: userns devel net device tty mapuid autoetc
|
||||||
|
Root: /var/lib/hakurei/base/org.debian (2)
|
||||||
Etc: /etc
|
Etc: /etc
|
||||||
Cover: /var/run/nscd
|
Cover: /var/run/nscd
|
||||||
Path: /run/current-system/sw/bin/chromium
|
Path: /run/current-system/sw/bin/chromium
|
||||||
@ -302,6 +304,8 @@ App
|
|||||||
"/run/user/150"
|
"/run/user/150"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc",
|
||||||
"auto_etc": true,
|
"auto_etc": true,
|
||||||
"cover": [
|
"cover": [
|
||||||
@ -430,6 +434,8 @@ App
|
|||||||
"/run/user/150"
|
"/run/user/150"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc",
|
||||||
"auto_etc": true,
|
"auto_etc": true,
|
||||||
"cover": [
|
"cover": [
|
||||||
@ -612,6 +618,8 @@ func Test_printPs(t *testing.T) {
|
|||||||
"/run/user/150"
|
"/run/user/150"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc",
|
||||||
"auto_etc": true,
|
"auto_etc": true,
|
||||||
"cover": [
|
"cover": [
|
||||||
|
@ -23,7 +23,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
hlog.Prepare("planterette")
|
hlog.Prepare("hpkg")
|
||||||
if err := os.Setenv("SHELL", shellPath); err != nil {
|
if err := os.Setenv("SHELL", shellPath); err != nil {
|
||||||
log.Fatalf("cannot set $SHELL: %v", err)
|
log.Fatalf("cannot set $SHELL: %v", err)
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ func main() {
|
|||||||
flagVerbose bool
|
flagVerbose bool
|
||||||
flagDropShell bool
|
flagDropShell bool
|
||||||
)
|
)
|
||||||
c := command.New(os.Stderr, log.Printf, "planterette", func([]string) error { internal.InstallOutput(flagVerbose); return nil }).
|
c := command.New(os.Stderr, log.Printf, "hpkg", func([]string) error { internal.InstallOutput(flagVerbose); return nil }).
|
||||||
Flag(&flagVerbose, "v", command.BoolFlag(false), "Print debug messages to the console").
|
Flag(&flagVerbose, "v", command.BoolFlag(false), "Print debug messages to the console").
|
||||||
Flag(&flagDropShell, "s", command.BoolFlag(false), "Drop to a shell in place of next hakurei action")
|
Flag(&flagDropShell, "s", command.BoolFlag(false), "Drop to a shell in place of next hakurei action")
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Look up paths to programs started by planterette.
|
Look up paths to programs started by hpkg.
|
||||||
This is done here to ease error handling as cleanup is not yet required.
|
This is done here to ease error handling as cleanup is not yet required.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ func main() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
var workDir string
|
var workDir string
|
||||||
if p, err := os.MkdirTemp("", "planterette.*"); err != nil {
|
if p, err := os.MkdirTemp("", "hpkg.*"); err != nil {
|
||||||
log.Printf("cannot create temporary directory: %v", err)
|
log.Printf("cannot create temporary directory: %v", err)
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
@ -9,7 +9,7 @@ let
|
|||||||
buildPackage = self.buildPackage.${system};
|
buildPackage = self.buildPackage.${system};
|
||||||
in
|
in
|
||||||
nixosTest {
|
nixosTest {
|
||||||
name = "planterette";
|
name = "hpkg";
|
||||||
nodes.machine = {
|
nodes.machine = {
|
||||||
environment.etc = {
|
environment.etc = {
|
||||||
"foot.pkg".source = callPackage ./foot.nix { inherit buildPackage; };
|
"foot.pkg".source = callPackage ./foot.nix { inherit buildPackage; };
|
@ -79,15 +79,15 @@ print(machine.succeed("sudo -u alice -i hakurei version"))
|
|||||||
machine.wait_for_file("/run/user/1000/wayland-1")
|
machine.wait_for_file("/run/user/1000/wayland-1")
|
||||||
machine.wait_for_file("/tmp/sway-ipc.sock")
|
machine.wait_for_file("/tmp/sway-ipc.sock")
|
||||||
|
|
||||||
# Prepare planterette directory:
|
# Prepare hpkg directory:
|
||||||
machine.succeed("install -dm 0700 -o alice -g users /var/lib/hakurei/1000")
|
machine.succeed("install -dm 0700 -o alice -g users /var/lib/hakurei/1000")
|
||||||
|
|
||||||
# Install planterette app:
|
# Install hpkg app:
|
||||||
swaymsg("exec planterette -v install /etc/foot.pkg && touch /tmp/planterette-install-ok")
|
swaymsg("exec hpkg -v install /etc/foot.pkg && touch /tmp/hpkg-install-ok")
|
||||||
machine.wait_for_file("/tmp/planterette-install-ok")
|
machine.wait_for_file("/tmp/hpkg-install-ok")
|
||||||
|
|
||||||
# Start app (foot) with Wayland enablement:
|
# Start app (foot) with Wayland enablement:
|
||||||
swaymsg("exec planterette -v start org.codeberg.dnkl.foot")
|
swaymsg("exec hpkg -v start org.codeberg.dnkl.foot")
|
||||||
wait_for_window("hakurei@machine-foot")
|
wait_for_window("hakurei@machine-foot")
|
||||||
machine.send_chars("clear; wayland-info && touch /tmp/success-client\n")
|
machine.send_chars("clear; wayland-info && touch /tmp/success-client\n")
|
||||||
machine.wait_for_file("/tmp/hakurei.1000/tmpdir/2/success-client")
|
machine.wait_for_file("/tmp/hakurei.1000/tmpdir/2/success-client")
|
65
container/autoetc.go
Normal file
65
container/autoetc.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() { gob.Register(new(AutoEtcOp)) }
|
||||||
|
|
||||||
|
// Etc appends an [Op] that 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.
|
||||||
|
func (f *Ops) Etc(host, prefix string) *Ops {
|
||||||
|
e := &AutoEtcOp{prefix}
|
||||||
|
f.Mkdir("/etc", 0755)
|
||||||
|
f.Bind(host, e.hostPath(), 0)
|
||||||
|
*f = append(*f, e)
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
type AutoEtcOp struct{ Prefix string }
|
||||||
|
|
||||||
|
func (e *AutoEtcOp) early(*Params) error { return nil }
|
||||||
|
func (e *AutoEtcOp) apply(*Params) error {
|
||||||
|
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.hostPath())); err != nil {
|
||||||
|
return wrapErrSelf(err)
|
||||||
|
} else {
|
||||||
|
for _, ent := range d {
|
||||||
|
n := ent.Name()
|
||||||
|
switch n {
|
||||||
|
case ".host":
|
||||||
|
|
||||||
|
case "passwd":
|
||||||
|
case "group":
|
||||||
|
|
||||||
|
case "mtab":
|
||||||
|
if err = os.Symlink("/proc/mounts", target+n); err != nil {
|
||||||
|
return wrapErrSelf(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
if err = os.Symlink(rel+n, target+n); err != nil {
|
||||||
|
return wrapErrSelf(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (e *AutoEtcOp) hostPath() string { return "/etc/" + e.hostRel() }
|
||||||
|
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
||||||
|
|
||||||
|
func (e *AutoEtcOp) Is(op Op) bool {
|
||||||
|
ve, ok := op.(*AutoEtcOp)
|
||||||
|
return ok && ((e == nil && ve == nil) || (e != nil && ve != nil && *e == *ve))
|
||||||
|
}
|
||||||
|
func (*AutoEtcOp) prefix() string { return "setting up" }
|
||||||
|
func (e *AutoEtcOp) String() string { return fmt.Sprintf("auto etc %s", e.Prefix) }
|
91
container/autoroot.go
Normal file
91
container/autoroot.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package container
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
. "syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() { gob.Register(new(AutoRootOp)) }
|
||||||
|
|
||||||
|
// Root appends an [Op] that expands a directory into a toplevel bind mount mirror on container root.
|
||||||
|
// This is not a generic setup op. It is implemented here to reduce ipc overhead.
|
||||||
|
func (f *Ops) Root(host, prefix string, flags int) *Ops {
|
||||||
|
*f = append(*f, &AutoRootOp{host, prefix, flags, nil})
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
type AutoRootOp struct {
|
||||||
|
Host, Prefix string
|
||||||
|
// passed through to bindMount
|
||||||
|
Flags int
|
||||||
|
|
||||||
|
// obtained during early;
|
||||||
|
// these wrap the underlying Op because BindMountOp is relatively complex,
|
||||||
|
// so duplicating that code would be unwise
|
||||||
|
resolved []Op
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AutoRootOp) early(params *Params) error {
|
||||||
|
if !path.IsAbs(r.Host) {
|
||||||
|
return msg.WrapErr(EBADE, fmt.Sprintf("path %q is not absolute", r.Host))
|
||||||
|
}
|
||||||
|
|
||||||
|
if d, err := os.ReadDir(r.Host); err != nil {
|
||||||
|
return wrapErrSelf(err)
|
||||||
|
} else {
|
||||||
|
r.resolved = make([]Op, 0, len(d))
|
||||||
|
for _, ent := range d {
|
||||||
|
name := ent.Name()
|
||||||
|
if IsAutoRootBindable(name) {
|
||||||
|
op := &BindMountOp{
|
||||||
|
Source: path.Join(r.Host, name),
|
||||||
|
Target: "/" + name,
|
||||||
|
Flags: r.Flags,
|
||||||
|
}
|
||||||
|
if err = op.early(params); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.resolved = append(r.resolved, op)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AutoRootOp) apply(params *Params) error {
|
||||||
|
for _, op := range r.resolved {
|
||||||
|
msg.Verbosef("%s %s", op.prefix(), op)
|
||||||
|
if err := op.apply(params); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *AutoRootOp) Is(op Op) bool {
|
||||||
|
vr, ok := op.(*AutoRootOp)
|
||||||
|
return ok && ((r == nil && vr == nil) || (r != nil && vr != nil &&
|
||||||
|
r.Host == vr.Host && r.Prefix == vr.Prefix && r.Flags == vr.Flags))
|
||||||
|
}
|
||||||
|
func (*AutoRootOp) prefix() string { return "setting up" }
|
||||||
|
func (r *AutoRootOp) String() string {
|
||||||
|
return fmt.Sprintf("auto root %q prefix %s flags %#x", r.Host, r.Prefix, r.Flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAutoRootBindable returns whether a dir entry name is selected for AutoRoot.
|
||||||
|
func IsAutoRootBindable(name string) bool {
|
||||||
|
switch name {
|
||||||
|
case "proc":
|
||||||
|
case "dev":
|
||||||
|
case "tmp":
|
||||||
|
case "mnt":
|
||||||
|
case "etc":
|
||||||
|
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
@ -28,7 +28,9 @@ const (
|
|||||||
ignore = "\x00"
|
ignore = "\x00"
|
||||||
ignoreV = -1
|
ignoreV = -1
|
||||||
|
|
||||||
pathWantMnt = "/etc/hakurei/want-mnt"
|
pathPrefix = "/etc/hakurei/"
|
||||||
|
pathWantMnt = pathPrefix + "want-mnt"
|
||||||
|
pathReadonly = pathPrefix + "readonly"
|
||||||
)
|
)
|
||||||
|
|
||||||
var containerTestCases = []struct {
|
var containerTestCases = []struct {
|
||||||
@ -36,6 +38,7 @@ var containerTestCases = []struct {
|
|||||||
filter bool
|
filter bool
|
||||||
session bool
|
session bool
|
||||||
net bool
|
net bool
|
||||||
|
ro bool
|
||||||
ops *container.Ops
|
ops *container.Ops
|
||||||
|
|
||||||
mnt []*vfs.MountInfoEntry
|
mnt []*vfs.MountInfoEntry
|
||||||
@ -46,26 +49,26 @@ var containerTestCases = []struct {
|
|||||||
flags seccomp.ExportFlag
|
flags seccomp.ExportFlag
|
||||||
presets seccomp.FilterPreset
|
presets seccomp.FilterPreset
|
||||||
}{
|
}{
|
||||||
{"minimal", true, false, false,
|
{"minimal", true, false, false, true,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1000, 100, nil, 0, seccomp.PresetStrict},
|
1000, 100, nil, 0, seccomp.PresetStrict},
|
||||||
{"allow", true, true, true,
|
{"allow", true, true, true, false,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1000, 100, nil, 0, seccomp.PresetExt | seccomp.PresetDenyDevel},
|
1000, 100, nil, 0, seccomp.PresetExt | seccomp.PresetDenyDevel},
|
||||||
{"no filter", false, true, true,
|
{"no filter", false, true, true, true,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1000, 100, nil, 0, seccomp.PresetExt},
|
1000, 100, nil, 0, seccomp.PresetExt},
|
||||||
{"custom rules", true, true, true,
|
{"custom rules", true, true, true, false,
|
||||||
new(container.Ops), nil,
|
new(container.Ops), nil,
|
||||||
1, 31, []seccomp.NativeRule{{seccomp.ScmpSyscall(syscall.SYS_SETUID), seccomp.ScmpErrno(syscall.EPERM), nil}}, 0, seccomp.PresetExt},
|
1, 31, []seccomp.NativeRule{{seccomp.ScmpSyscall(syscall.SYS_SETUID), seccomp.ScmpErrno(syscall.EPERM), nil}}, 0, seccomp.PresetExt},
|
||||||
{"tmpfs", true, false, false,
|
{"tmpfs", true, false, false, true,
|
||||||
new(container.Ops).
|
new(container.Ops).
|
||||||
Tmpfs(hst.Tmp, 0, 0755),
|
Tmpfs(hst.Tmp, 0, 0755),
|
||||||
[]*vfs.MountInfoEntry{
|
[]*vfs.MountInfoEntry{
|
||||||
ent("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "tmpfs", ignore),
|
ent("/", hst.Tmp, "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", ignore),
|
||||||
},
|
},
|
||||||
9, 9, nil, 0, seccomp.PresetStrict},
|
9, 9, 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, false,
|
||||||
new(container.Ops).
|
new(container.Ops).
|
||||||
Dev("/dev").
|
Dev("/dev").
|
||||||
Mqueue("/dev/mqueue"),
|
Mqueue("/dev/mqueue"),
|
||||||
@ -140,6 +143,7 @@ func TestContainer(t *testing.T) {
|
|||||||
c.HostNet = tc.net
|
c.HostNet = tc.net
|
||||||
|
|
||||||
c.
|
c.
|
||||||
|
Readonly(pathReadonly, 0755).
|
||||||
Tmpfs("/tmp", 0, 0755).
|
Tmpfs("/tmp", 0, 0755).
|
||||||
Place("/etc/hostname", []byte(c.Hostname))
|
Place("/etc/hostname", []byte(c.Hostname))
|
||||||
// needs /proc to check mountinfo
|
// needs /proc to check mountinfo
|
||||||
@ -158,8 +162,10 @@ func TestContainer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
mnt = append(mnt, tc.mnt...)
|
mnt = append(mnt, tc.mnt...)
|
||||||
mnt = append(mnt,
|
mnt = append(mnt,
|
||||||
|
// Readonly(pathReadonly, 0755)
|
||||||
|
ent("/", pathReadonly, "ro,nosuid,nodev", "tmpfs", "readonly", ignore),
|
||||||
// Tmpfs("/tmp", 0, 0755)
|
// Tmpfs("/tmp", 0, 0755)
|
||||||
ent("/", "/tmp", "rw,nosuid,nodev,relatime", "tmpfs", "tmpfs", ignore),
|
ent("/", "/tmp", "rw,nosuid,nodev,relatime", "tmpfs", "ephemeral", ignore),
|
||||||
// Place("/etc/hostname", []byte(hostname))
|
// Place("/etc/hostname", []byte(hostname))
|
||||||
ent(ignore, "/etc/hostname", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", ignore),
|
ent(ignore, "/etc/hostname", "ro,nosuid,nodev,relatime", "tmpfs", "rootfs", ignore),
|
||||||
// Proc("/proc")
|
// Proc("/proc")
|
||||||
@ -173,6 +179,10 @@ func TestContainer(t *testing.T) {
|
|||||||
}
|
}
|
||||||
c.Place(pathWantMnt, want.Bytes())
|
c.Place(pathWantMnt, want.Bytes())
|
||||||
|
|
||||||
|
if tc.ro {
|
||||||
|
c.Remount("/", syscall.MS_RDONLY)
|
||||||
|
}
|
||||||
|
|
||||||
if err := c.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)
|
||||||
@ -309,6 +319,10 @@ func init() {
|
|||||||
return fmt.Errorf("/etc/hostname: %q, want %q", string(p), wantHost)
|
return fmt.Errorf("/etc/hostname: %q, want %q", string(p), wantHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, err := os.Create(pathReadonly + "/nonexistent"); !errors.Is(err, syscall.EROFS) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
var fail bool
|
var fail bool
|
||||||
|
|
||||||
@ -321,6 +335,11 @@ func init() {
|
|||||||
return fmt.Errorf("cannot close expected mount points: %v", err)
|
return fmt.Errorf("cannot close expected mount points: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tc.ro && len(mnt) > 0 {
|
||||||
|
// Remount("/", syscall.MS_RDONLY)
|
||||||
|
mnt[0].VfsOptstr = "ro,nosuid,nodev"
|
||||||
|
}
|
||||||
|
|
||||||
var d *vfs.MountInfoDecoder
|
var d *vfs.MountInfoDecoder
|
||||||
if f, err := os.Open("/proc/self/mountinfo"); err != nil {
|
if f, err := os.Open("/proc/self/mountinfo"); err != nil {
|
||||||
return fmt.Errorf("cannot open mountinfo: %v", err)
|
return fmt.Errorf("cannot open mountinfo: %v", err)
|
||||||
|
@ -121,6 +121,10 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
log.Fatalf("cannot make / rslave: %v", err)
|
log.Fatalf("cannot make / rslave: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* early is called right before pivot_root into intermediate root;
|
||||||
|
this step is mostly for gathering information that would otherwise be difficult to obtain
|
||||||
|
via library functions after pivot_root, and implementations are expected to avoid changing
|
||||||
|
the state of the mount namespace */
|
||||||
for i, op := range *params.Ops {
|
for i, op := range *params.Ops {
|
||||||
if op == nil {
|
if op == nil {
|
||||||
log.Fatalf("invalid op %d", i)
|
log.Fatalf("invalid op %d", i)
|
||||||
@ -159,6 +163,10 @@ func Init(prepare func(prefix string), setVerbose func(verbose bool)) {
|
|||||||
log.Fatalf("%v", err)
|
log.Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* apply is called right after pivot_root and entering the new root;
|
||||||
|
this step sets up the container filesystem, and implementations are expected to keep the host root
|
||||||
|
and sysroot mount points intact but otherwise can do whatever they need to;
|
||||||
|
chdir is allowed but discouraged */
|
||||||
for i, op := range *params.Ops {
|
for i, op := range *params.Ops {
|
||||||
// ops already checked during early setup
|
// ops already checked during early setup
|
||||||
msg.Verbosef("%s %s", op.prefix(), op)
|
msg.Verbosef("%s %s", op.prefix(), op)
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"hakurei.app/container/vfs"
|
"hakurei.app/container/vfs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// bindMount mounts source on target and recursively applies flags if MS_REC is set.
|
||||||
func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) error {
|
func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) error {
|
||||||
if eq {
|
if eq {
|
||||||
msg.Verbosef("resolved %q flags %#x", target, flags)
|
msg.Verbosef("resolved %q flags %#x", target, flags)
|
||||||
@ -22,6 +23,11 @@ func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) err
|
|||||||
fmt.Sprintf("cannot mount %q on %q:", source, target))
|
fmt.Sprintf("cannot mount %q on %q:", source, target))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p.remount(target, flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remount applies flags on target, recursively if MS_REC is set.
|
||||||
|
func (p *procPaths) remount(target string, flags uintptr) error {
|
||||||
var targetFinal string
|
var targetFinal string
|
||||||
if v, err := filepath.EvalSymlinks(target); err != nil {
|
if v, err := filepath.EvalSymlinks(target); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
@ -83,6 +89,7 @@ func (p *procPaths) bindMount(source, target string, flags uintptr, eq bool) err
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remountWithFlags remounts mount point described by [vfs.MountInfoNode].
|
||||||
func remountWithFlags(n *vfs.MountInfoNode, mf uintptr) error {
|
func remountWithFlags(n *vfs.MountInfoNode, mf uintptr) error {
|
||||||
kf, unmatched := n.Flags()
|
kf, unmatched := n.Flags()
|
||||||
if len(unmatched) != 0 {
|
if len(unmatched) != 0 {
|
||||||
@ -97,7 +104,7 @@ func remountWithFlags(n *vfs.MountInfoNode, mf uintptr) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mountTmpfs(fsname, name string, size int, perm os.FileMode) error {
|
func mountTmpfs(fsname, name string, flags uintptr, size int, perm os.FileMode) error {
|
||||||
target := toSysroot(name)
|
target := toSysroot(name)
|
||||||
if err := os.MkdirAll(target, parentPerm(perm)); err != nil {
|
if err := os.MkdirAll(target, parentPerm(perm)); err != nil {
|
||||||
return wrapErrSelf(err)
|
return wrapErrSelf(err)
|
||||||
@ -107,7 +114,7 @@ func mountTmpfs(fsname, name string, size int, perm os.FileMode) error {
|
|||||||
opt += fmt.Sprintf(",size=%d", size)
|
opt += fmt.Sprintf(",size=%d", size)
|
||||||
}
|
}
|
||||||
return wrapErrSuffix(
|
return wrapErrSuffix(
|
||||||
Mount(fsname, target, "tmpfs", MS_NOSUID|MS_NODEV, opt),
|
Mount(fsname, target, "tmpfs", flags, opt),
|
||||||
fmt.Sprintf("cannot mount tmpfs on %q:", name))
|
fmt.Sprintf("cannot mount tmpfs on %q:", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
106
container/ops.go
106
container/ops.go
@ -33,6 +33,32 @@ type (
|
|||||||
// Grow grows the slice Ops points to using [slices.Grow].
|
// Grow grows the slice Ops points to using [slices.Grow].
|
||||||
func (f *Ops) Grow(n int) { *f = slices.Grow(*f, n) }
|
func (f *Ops) Grow(n int) { *f = slices.Grow(*f, n) }
|
||||||
|
|
||||||
|
func init() { gob.Register(new(RemountOp)) }
|
||||||
|
|
||||||
|
// Remount appends an [Op] that applies [RemountOp.Flags] on container path [RemountOp.Target].
|
||||||
|
func (f *Ops) Remount(target string, flags uintptr) *Ops {
|
||||||
|
*f = append(*f, &RemountOp{target, flags})
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
type RemountOp struct {
|
||||||
|
Target string
|
||||||
|
Flags uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*RemountOp) early(*Params) error { return nil }
|
||||||
|
func (r *RemountOp) apply(*Params) error {
|
||||||
|
if !path.IsAbs(r.Target) {
|
||||||
|
return msg.WrapErr(EBADE, fmt.Sprintf("path %q is not absolute", r.Target))
|
||||||
|
}
|
||||||
|
return wrapErrSuffix(hostProc.remount(toSysroot(r.Target), r.Flags),
|
||||||
|
fmt.Sprintf("cannot remount %q:", r.Target))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RemountOp) Is(op Op) bool { vr, ok := op.(*RemountOp); return ok && *r == *vr }
|
||||||
|
func (*RemountOp) prefix() string { return "remounting" }
|
||||||
|
func (r *RemountOp) String() string { return fmt.Sprintf("%q flags %#x", r.Target, r.Flags) }
|
||||||
|
|
||||||
func init() { gob.Register(new(BindMountOp)) }
|
func init() { gob.Register(new(BindMountOp)) }
|
||||||
|
|
||||||
// Bind appends an [Op] that bind mounts host path [BindMountOp.Source] on container path [BindMountOp.Target].
|
// Bind appends an [Op] that bind mounts host path [BindMountOp.Source] on container path [BindMountOp.Target].
|
||||||
@ -118,7 +144,7 @@ func (b *BindMountOp) String() string {
|
|||||||
if b.Source == b.Target {
|
if b.Source == b.Target {
|
||||||
return fmt.Sprintf("%q flags %#x", b.Source, b.Flags)
|
return fmt.Sprintf("%q flags %#x", b.Source, b.Flags)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%q on %q flags %#x", b.Source, b.Target, b.Flags&BindWritable)
|
return fmt.Sprintf("%q on %q flags %#x", b.Source, b.Target, b.Flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { gob.Register(new(MountProcOp)) }
|
func init() { gob.Register(new(MountProcOp)) }
|
||||||
@ -170,7 +196,7 @@ func (d MountDevOp) apply(params *Params) error {
|
|||||||
}
|
}
|
||||||
target := toSysroot(v)
|
target := toSysroot(v)
|
||||||
|
|
||||||
if err := mountTmpfs("devtmpfs", v, 0, params.ParentPerm); err != nil {
|
if err := mountTmpfs("devtmpfs", v, MS_NOSUID|MS_NODEV, 0, params.ParentPerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,14 +306,22 @@ func init() { gob.Register(new(MountTmpfsOp)) }
|
|||||||
|
|
||||||
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
// Tmpfs appends an [Op] that mounts tmpfs on container path [MountTmpfsOp.Path].
|
||||||
func (f *Ops) Tmpfs(dest string, size int, perm os.FileMode) *Ops {
|
func (f *Ops) Tmpfs(dest string, size int, perm os.FileMode) *Ops {
|
||||||
*f = append(*f, &MountTmpfsOp{dest, size, perm})
|
*f = append(*f, &MountTmpfsOp{"ephemeral", dest, MS_NOSUID | MS_NODEV, size, perm})
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Readonly appends an [Op] that mounts read-only tmpfs on container path [MountTmpfsOp.Path].
|
||||||
|
func (f *Ops) Readonly(dest string, perm os.FileMode) *Ops {
|
||||||
|
*f = append(*f, &MountTmpfsOp{"readonly", dest, MS_RDONLY | MS_NOSUID | MS_NODEV, 0, perm})
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
type MountTmpfsOp struct {
|
type MountTmpfsOp struct {
|
||||||
Path string
|
FSName string
|
||||||
Size int
|
Path string
|
||||||
Perm os.FileMode
|
Flags uintptr
|
||||||
|
Size int
|
||||||
|
Perm os.FileMode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *MountTmpfsOp) early(*Params) error { return nil }
|
func (t *MountTmpfsOp) early(*Params) error { return nil }
|
||||||
@ -298,7 +332,7 @@ func (t *MountTmpfsOp) apply(*Params) error {
|
|||||||
if t.Size < 0 || t.Size > math.MaxUint>>1 {
|
if t.Size < 0 || t.Size > math.MaxUint>>1 {
|
||||||
return msg.WrapErr(EBADE, fmt.Sprintf("size %d out of bounds", t.Size))
|
return msg.WrapErr(EBADE, fmt.Sprintf("size %d out of bounds", t.Size))
|
||||||
}
|
}
|
||||||
return mountTmpfs("tmpfs", t.Path, t.Size, t.Perm)
|
return mountTmpfs(t.FSName, t.Path, t.Flags, t.Size, t.Perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *MountTmpfsOp) Is(op Op) bool { vt, ok := op.(*MountTmpfsOp); return ok && *t == *vt }
|
func (t *MountTmpfsOp) Is(op Op) bool { vt, ok := op.(*MountTmpfsOp); return ok && *t == *vt }
|
||||||
@ -440,61 +474,3 @@ func (*TmpfileOp) prefix() string { return "placing" }
|
|||||||
func (t *TmpfileOp) String() string {
|
func (t *TmpfileOp) String() string {
|
||||||
return fmt.Sprintf("tmpfile %q (%d bytes)", t.Path, len(t.Data))
|
return fmt.Sprintf("tmpfile %q (%d bytes)", t.Path, len(t.Data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { gob.Register(new(AutoEtcOp)) }
|
|
||||||
|
|
||||||
// Etc appends an [Op] that 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.
|
|
||||||
func (f *Ops) Etc(host, prefix string) *Ops {
|
|
||||||
e := &AutoEtcOp{prefix}
|
|
||||||
f.Mkdir("/etc", 0755)
|
|
||||||
f.Bind(host, e.hostPath(), 0)
|
|
||||||
*f = append(*f, e)
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
type AutoEtcOp struct{ Prefix string }
|
|
||||||
|
|
||||||
func (e *AutoEtcOp) early(*Params) error { return nil }
|
|
||||||
func (e *AutoEtcOp) apply(*Params) error {
|
|
||||||
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.hostPath())); err != nil {
|
|
||||||
return wrapErrSelf(err)
|
|
||||||
} else {
|
|
||||||
for _, ent := range d {
|
|
||||||
n := ent.Name()
|
|
||||||
switch n {
|
|
||||||
case ".host":
|
|
||||||
|
|
||||||
case "passwd":
|
|
||||||
case "group":
|
|
||||||
|
|
||||||
case "mtab":
|
|
||||||
if err = os.Symlink("/proc/mounts", target+n); err != nil {
|
|
||||||
return wrapErrSelf(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
if err = os.Symlink(rel+n, target+n); err != nil {
|
|
||||||
return wrapErrSelf(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (e *AutoEtcOp) hostPath() string { return "/etc/" + e.hostRel() }
|
|
||||||
func (e *AutoEtcOp) hostRel() string { return ".host/" + e.Prefix }
|
|
||||||
|
|
||||||
func (e *AutoEtcOp) Is(op Op) bool {
|
|
||||||
ve, ok := op.(*AutoEtcOp)
|
|
||||||
return ok && ((e == nil && ve == nil) || (e != nil && ve != nil && *e == *ve))
|
|
||||||
}
|
|
||||||
func (*AutoEtcOp) prefix() string { return "setting up" }
|
|
||||||
func (e *AutoEtcOp) String() string { return fmt.Sprintf("auto etc %s", e.Prefix) }
|
|
||||||
|
2
dist/install.sh
vendored
2
dist/install.sh
vendored
@ -2,7 +2,7 @@
|
|||||||
cd "$(dirname -- "$0")" || exit 1
|
cd "$(dirname -- "$0")" || exit 1
|
||||||
|
|
||||||
install -vDm0755 "bin/hakurei" "${HAKUREI_INSTALL_PREFIX}/usr/bin/hakurei"
|
install -vDm0755 "bin/hakurei" "${HAKUREI_INSTALL_PREFIX}/usr/bin/hakurei"
|
||||||
install -vDm0755 "bin/planterette" "${HAKUREI_INSTALL_PREFIX}/usr/bin/planterette"
|
install -vDm0755 "bin/hpkg" "${HAKUREI_INSTALL_PREFIX}/usr/bin/hpkg"
|
||||||
|
|
||||||
install -vDm6511 "bin/hsu" "${HAKUREI_INSTALL_PREFIX}/usr/bin/hsu"
|
install -vDm6511 "bin/hsu" "${HAKUREI_INSTALL_PREFIX}/usr/bin/hsu"
|
||||||
if [ ! -f "${HAKUREI_INSTALL_PREFIX}/etc/hsurc" ]; then
|
if [ ! -f "${HAKUREI_INSTALL_PREFIX}/etc/hsurc" ]; then
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
buildPackage = forAllSystems (
|
buildPackage = forAllSystems (
|
||||||
system:
|
system:
|
||||||
nixpkgsFor.${system}.callPackage (
|
nixpkgsFor.${system}.callPackage (
|
||||||
import ./cmd/planterette/build.nix {
|
import ./cmd/hpkg/build.nix {
|
||||||
inherit
|
inherit
|
||||||
nixpkgsFor
|
nixpkgsFor
|
||||||
system
|
system
|
||||||
@ -69,7 +69,7 @@
|
|||||||
withRace = true;
|
withRace = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
planterette = callPackage ./cmd/planterette/test { inherit system self; };
|
hpkg = callPackage ./cmd/hpkg/test { inherit system self; };
|
||||||
|
|
||||||
formatting = runCommandLocal "check-formatting" { nativeBuildInputs = [ nixfmt-rfc-style ]; } ''
|
formatting = runCommandLocal "check-formatting" { nativeBuildInputs = [ nixfmt-rfc-style ]; } ''
|
||||||
cd ${./.}
|
cd ${./.}
|
||||||
@ -125,7 +125,7 @@
|
|||||||
glibc
|
glibc
|
||||||
xdg-dbus-proxy
|
xdg-dbus-proxy
|
||||||
|
|
||||||
# planterette
|
# hpkg
|
||||||
zstd
|
zstd
|
||||||
gnutar
|
gnutar
|
||||||
coreutils
|
coreutils
|
||||||
|
@ -6,6 +6,20 @@ import (
|
|||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SourceTmpfs causes tmpfs to be mounted on [FilesystemConfig.Dst]
|
||||||
|
// when assigned to [FilesystemConfig.Src].
|
||||||
|
SourceTmpfs = "tmpfs"
|
||||||
|
|
||||||
|
// TmpfsPerm is the permission bits for tmpfs mount points
|
||||||
|
// configured through [FilesystemConfig].
|
||||||
|
TmpfsPerm = 0755
|
||||||
|
|
||||||
|
// TmpfsSize is the size for tmpfs mount points
|
||||||
|
// configured through [FilesystemConfig].
|
||||||
|
TmpfsSize = 0
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
// ContainerConfig describes the container configuration baseline to which the app implementation adds upon.
|
// ContainerConfig describes the container configuration baseline to which the app implementation adds upon.
|
||||||
ContainerConfig struct {
|
ContainerConfig struct {
|
||||||
@ -45,10 +59,17 @@ type (
|
|||||||
// create symlinks inside container filesystem
|
// create symlinks inside container filesystem
|
||||||
Link [][2]string `json:"symlink"`
|
Link [][2]string `json:"symlink"`
|
||||||
|
|
||||||
|
// automatically bind mount top-level directories to container root;
|
||||||
|
// the zero value disables this behaviour
|
||||||
|
AutoRoot string `json:"auto_root,omitempty"`
|
||||||
|
// extra flags for AutoRoot
|
||||||
|
RootFlags int `json:"root_flags,omitempty"`
|
||||||
|
|
||||||
// read-only /etc directory
|
// read-only /etc directory
|
||||||
Etc string `json:"etc,omitempty"`
|
Etc string `json:"etc,omitempty"`
|
||||||
// automatically set up /etc symlinks
|
// automatically set up /etc symlinks
|
||||||
AutoEtc bool `json:"auto_etc"`
|
AutoEtc bool `json:"auto_etc"`
|
||||||
|
|
||||||
// cover these paths or create them if they do not already exist
|
// cover these paths or create them if they do not already exist
|
||||||
Cover []string `json:"cover"`
|
Cover []string `json:"cover"`
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package hst
|
package hst
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/system"
|
"hakurei.app/system"
|
||||||
"hakurei.app/system/dbus"
|
"hakurei.app/system/dbus"
|
||||||
@ -85,10 +86,12 @@ func Template() *Config {
|
|||||||
Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
|
Dst: "/data/data/org.chromium.Chromium", Write: true, Must: true},
|
||||||
{Src: "/dev/dri", Device: true},
|
{Src: "/dev/dri", Device: true},
|
||||||
},
|
},
|
||||||
Link: [][2]string{{"/run/user/65534", "/run/user/150"}},
|
Link: [][2]string{{"/run/user/65534", "/run/user/150"}},
|
||||||
Etc: "/etc",
|
AutoRoot: "/var/lib/hakurei/base/org.debian",
|
||||||
AutoEtc: true,
|
RootFlags: container.BindWritable,
|
||||||
Cover: []string{"/var/run/nscd"},
|
Etc: "/etc",
|
||||||
|
AutoEtc: true,
|
||||||
|
Cover: []string{"/var/run/nscd"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +126,8 @@ func TestTemplate(t *testing.T) {
|
|||||||
"/run/user/150"
|
"/run/user/150"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"auto_root": "/var/lib/hakurei/base/org.debian",
|
||||||
|
"root_flags": 2,
|
||||||
"etc": "/etc",
|
"etc": "/etc",
|
||||||
"auto_etc": true,
|
"auto_etc": true,
|
||||||
"cover": [
|
"cover": [
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package app_test
|
package app_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
"hakurei.app/hst"
|
"hakurei.app/hst"
|
||||||
@ -141,7 +143,8 @@ var testCasesNixos = []sealTestCase{
|
|||||||
Place(hst.Tmp+"/pulse-cookie", nil).
|
Place(hst.Tmp+"/pulse-cookie", nil).
|
||||||
Bind("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/bus", "/run/user/1971/bus", 0).
|
Bind("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/bus", "/run/user/1971/bus", 0).
|
||||||
Bind("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", "/run/dbus/system_bus_socket", 0).
|
Bind("/tmp/hakurei.1971/8e2c76b066dabe574cf073bdb46eb5c1/system_bus_socket", "/run/dbus/system_bus_socket", 0).
|
||||||
Tmpfs("/var/run/nscd", 8192, 0755),
|
Tmpfs("/var/run/nscd", 8192, 0755).
|
||||||
|
Remount("/", syscall.MS_RDONLY),
|
||||||
SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyTTY | seccomp.PresetDenyDevel,
|
SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyTTY | seccomp.PresetDenyDevel,
|
||||||
HostNet: true,
|
HostNet: true,
|
||||||
ForwardCancel: true,
|
ForwardCancel: true,
|
||||||
|
@ -2,6 +2,7 @@ package app_test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
"hakurei.app/container/seccomp"
|
"hakurei.app/container/seccomp"
|
||||||
@ -42,22 +43,12 @@ var testCasesPd = []sealTestCase{
|
|||||||
"XDG_SESSION_TYPE=tty",
|
"XDG_SESSION_TYPE=tty",
|
||||||
},
|
},
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
Root("/", "4a450b6596d7bc15bd01780eb9a607ac", container.BindWritable).
|
||||||
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", container.BindWritable).
|
|
||||||
Bind("/boot", "/boot", container.BindWritable).
|
|
||||||
Bind("/home", "/home", container.BindWritable).
|
|
||||||
Bind("/lib", "/lib", container.BindWritable).
|
|
||||||
Bind("/lib64", "/lib64", container.BindWritable).
|
|
||||||
Bind("/nix", "/nix", container.BindWritable).
|
|
||||||
Bind("/root", "/root", container.BindWritable).
|
|
||||||
Bind("/run", "/run", container.BindWritable).
|
|
||||||
Bind("/srv", "/srv", container.BindWritable).
|
|
||||||
Bind("/sys", "/sys", container.BindWritable).
|
|
||||||
Bind("/usr", "/usr", container.BindWritable).
|
|
||||||
Bind("/var", "/var", container.BindWritable).
|
|
||||||
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
|
Readonly("/var/run/nscd", 0755).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
Tmpfs("/run/dbus", 8192, 0755).
|
Tmpfs("/run/dbus", 8192, 0755).
|
||||||
Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac").
|
Etc("/etc", "4a450b6596d7bc15bd01780eb9a607ac").
|
||||||
@ -67,7 +58,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
Bind("/home/chronos", "/home/chronos", container.BindWritable).
|
Bind("/home/chronos", "/home/chronos", container.BindWritable).
|
||||||
Place("/etc/passwd", []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")).
|
Place("/etc/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),
|
Remount("/", syscall.MS_RDONLY),
|
||||||
SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyDevel,
|
SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyDevel,
|
||||||
HostNet: true,
|
HostNet: true,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
@ -186,23 +177,13 @@ var testCasesPd = []sealTestCase{
|
|||||||
"XDG_SESSION_TYPE=tty",
|
"XDG_SESSION_TYPE=tty",
|
||||||
},
|
},
|
||||||
Ops: new(container.Ops).
|
Ops: new(container.Ops).
|
||||||
|
Root("/", "ebf083d1b175911782d413369b64ce7c", container.BindWritable).
|
||||||
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", container.BindWritable).
|
|
||||||
Bind("/boot", "/boot", container.BindWritable).
|
|
||||||
Bind("/home", "/home", container.BindWritable).
|
|
||||||
Bind("/lib", "/lib", container.BindWritable).
|
|
||||||
Bind("/lib64", "/lib64", container.BindWritable).
|
|
||||||
Bind("/nix", "/nix", container.BindWritable).
|
|
||||||
Bind("/root", "/root", container.BindWritable).
|
|
||||||
Bind("/run", "/run", container.BindWritable).
|
|
||||||
Bind("/srv", "/srv", container.BindWritable).
|
|
||||||
Bind("/sys", "/sys", container.BindWritable).
|
|
||||||
Bind("/usr", "/usr", container.BindWritable).
|
|
||||||
Bind("/var", "/var", container.BindWritable).
|
|
||||||
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/dri", "/dev/dri", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
Bind("/dev/kvm", "/dev/kvm", container.BindWritable|container.BindDevice|container.BindOptional).
|
||||||
|
Readonly("/var/run/nscd", 0755).
|
||||||
Tmpfs("/run/user/1971", 8192, 0755).
|
Tmpfs("/run/user/1971", 8192, 0755).
|
||||||
Tmpfs("/run/dbus", 8192, 0755).
|
Tmpfs("/run/dbus", 8192, 0755).
|
||||||
Etc("/etc", "ebf083d1b175911782d413369b64ce7c").
|
Etc("/etc", "ebf083d1b175911782d413369b64ce7c").
|
||||||
@ -217,7 +198,7 @@ var testCasesPd = []sealTestCase{
|
|||||||
Place(hst.Tmp+"/pulse-cookie", nil).
|
Place(hst.Tmp+"/pulse-cookie", nil).
|
||||||
Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/bus", "/run/user/65534/bus", 0).
|
Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/bus", "/run/user/65534/bus", 0).
|
||||||
Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", "/run/dbus/system_bus_socket", 0).
|
Bind("/tmp/hakurei.1971/ebf083d1b175911782d413369b64ce7c/system_bus_socket", "/run/dbus/system_bus_socket", 0).
|
||||||
Tmpfs("/var/run/nscd", 8192, 0755),
|
Remount("/", syscall.MS_RDONLY),
|
||||||
SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyDevel,
|
SeccompPresets: seccomp.PresetExt | seccomp.PresetDenyDevel,
|
||||||
HostNet: true,
|
HostNet: true,
|
||||||
RetainSession: true,
|
RetainSession: true,
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"maps"
|
"maps"
|
||||||
"path"
|
"path"
|
||||||
|
"slices"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"hakurei.app/container"
|
"hakurei.app/container"
|
||||||
@ -21,7 +22,7 @@ const preallocateOpsCount = 1 << 5
|
|||||||
|
|
||||||
// newContainer initialises [container.Params] via [hst.ContainerConfig].
|
// newContainer initialises [container.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) (*container.Params, map[string]string, error) {
|
func newContainer(s *hst.ContainerConfig, os sys.State, prefix string, 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
|
||||||
}
|
}
|
||||||
@ -72,6 +73,13 @@ func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*contain
|
|||||||
*gid = container.OverflowGid()
|
*gid = container.OverflowGid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.AutoRoot != "" {
|
||||||
|
if !path.IsAbs(s.AutoRoot) {
|
||||||
|
return nil, nil, fmt.Errorf("auto root target %q not absolute", s.AutoRoot)
|
||||||
|
}
|
||||||
|
params.Root(s.AutoRoot, prefix, s.RootFlags)
|
||||||
|
}
|
||||||
|
|
||||||
params.
|
params.
|
||||||
Proc("/proc").
|
Proc("/proc").
|
||||||
Tmpfs(hst.Tmp, 1<<12, 0755)
|
Tmpfs(hst.Tmp, 1<<12, 0755)
|
||||||
@ -120,12 +128,48 @@ func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*contain
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// evaluated path, input path
|
||||||
|
hidePathSource := make([][2]string, 0, len(s.Filesystem))
|
||||||
|
|
||||||
|
// AutoRoot is a collection of many BindMountOp internally
|
||||||
|
if s.AutoRoot != "" {
|
||||||
|
if d, err := os.ReadDir(s.AutoRoot); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
} else {
|
||||||
|
hidePathSource = slices.Grow(hidePathSource, len(d))
|
||||||
|
for _, ent := range d {
|
||||||
|
name := ent.Name()
|
||||||
|
if container.IsAutoRootBindable(name) {
|
||||||
|
name = path.Join(s.AutoRoot, name)
|
||||||
|
srcP := [2]string{name, name}
|
||||||
|
if err = evalSymlinks(os, &srcP[0]); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
hidePathSource = append(hidePathSource, srcP)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, c := range s.Filesystem {
|
for _, c := range s.Filesystem {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// special filesystems
|
||||||
|
switch c.Src {
|
||||||
|
case hst.SourceTmpfs:
|
||||||
|
if !path.IsAbs(c.Dst) {
|
||||||
|
return nil, nil, fmt.Errorf("tmpfs dst %q is not absolute", c.Dst)
|
||||||
|
}
|
||||||
|
if c.Write {
|
||||||
|
params.Tmpfs(c.Dst, hst.TmpfsSize, hst.TmpfsPerm)
|
||||||
|
} else {
|
||||||
|
params.Readonly(c.Dst, hst.TmpfsPerm)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if !path.IsAbs(c.Src) {
|
if !path.IsAbs(c.Src) {
|
||||||
return nil, nil, fmt.Errorf("src path %q is not absolute", c.Src)
|
return nil, nil, fmt.Errorf("src path %q is not absolute", c.Src)
|
||||||
}
|
}
|
||||||
@ -137,24 +181,11 @@ func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*contain
|
|||||||
return nil, nil, fmt.Errorf("dst path %q is not absolute", dest)
|
return nil, nil, fmt.Errorf("dst path %q is not absolute", dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
srcH := c.Src
|
p := [2]string{c.Src, c.Src}
|
||||||
if err := evalSymlinks(os, &srcH); err != nil {
|
if err := evalSymlinks(os, &p[0]); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
hidePathSource = append(hidePathSource, p)
|
||||||
for i := range hidePaths {
|
|
||||||
// skip matched entries
|
|
||||||
if hidePathMatch[i] {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if ok, err := deepContainsH(srcH, hidePaths[i]); err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
} else if ok {
|
|
||||||
hidePathMatch[i] = true
|
|
||||||
os.Printf("hiding paths from %q", c.Src)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var flags int
|
var flags int
|
||||||
if c.Write {
|
if c.Write {
|
||||||
@ -169,6 +200,22 @@ func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*contain
|
|||||||
params.Bind(c.Src, dest, flags)
|
params.Bind(c.Src, dest, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, p := range hidePathSource {
|
||||||
|
for i := range hidePaths {
|
||||||
|
// skip matched entries
|
||||||
|
if hidePathMatch[i] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := deepContainsH(p[0], hidePaths[i]); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
} else if ok {
|
||||||
|
hidePathMatch[i] = true
|
||||||
|
os.Printf("hiding path %q from %q", hidePaths[i], p[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cover matched paths
|
// cover matched paths
|
||||||
for i, ok := range hidePathMatch {
|
for i, ok := range hidePathMatch {
|
||||||
if ok {
|
if ok {
|
||||||
@ -180,6 +227,18 @@ func newContainer(s *hst.ContainerConfig, os sys.State, uid, gid *int) (*contain
|
|||||||
params.Link(l[0], l[1])
|
params.Link(l[0], l[1])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !s.AutoEtc {
|
||||||
|
if s.Etc != "" {
|
||||||
|
params.Bind(s.Etc, "/etc", 0)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
etcPath := s.Etc
|
||||||
|
if etcPath == "" {
|
||||||
|
etcPath = "/etc"
|
||||||
|
}
|
||||||
|
params.Etc(etcPath, prefix)
|
||||||
|
}
|
||||||
|
|
||||||
return params, maps.Clone(s.Env), nil
|
return params, maps.Clone(s.Env), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -241,33 +241,11 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
Net: true,
|
Net: true,
|
||||||
Tty: true,
|
Tty: true,
|
||||||
AutoEtc: true,
|
AutoEtc: true,
|
||||||
}
|
|
||||||
// bind entries in /
|
|
||||||
if d, err := sys.ReadDir("/"); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
b := make([]*hst.FilesystemConfig, 0, len(d))
|
|
||||||
for _, ent := range d {
|
|
||||||
p := "/" + ent.Name()
|
|
||||||
switch p {
|
|
||||||
case "/proc":
|
|
||||||
case "/dev":
|
|
||||||
case "/tmp":
|
|
||||||
case "/mnt":
|
|
||||||
case "/etc":
|
|
||||||
|
|
||||||
default:
|
AutoRoot: "/",
|
||||||
b = append(b, &hst.FilesystemConfig{Src: p, Write: true, Must: true})
|
RootFlags: container.BindWritable,
|
||||||
}
|
|
||||||
}
|
|
||||||
conf.Filesystem = append(conf.Filesystem, b...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide nscd from sandbox if present
|
|
||||||
nscd := "/var/run/nscd"
|
|
||||||
if _, err := sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) {
|
|
||||||
conf.Cover = append(conf.Cover, nscd)
|
|
||||||
}
|
|
||||||
// bind GPU stuff
|
// bind GPU stuff
|
||||||
if config.Enablements&(system.EX11|system.EWayland) != 0 {
|
if config.Enablements&(system.EX11|system.EWayland) != 0 {
|
||||||
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/dri", Device: true})
|
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/dri", Device: true})
|
||||||
@ -275,6 +253,12 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
// opportunistically bind kvm
|
// opportunistically bind kvm
|
||||||
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/kvm", Device: true})
|
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Src: "/dev/kvm", Device: true})
|
||||||
|
|
||||||
|
// hide nscd from container if present
|
||||||
|
const nscd = "/var/run/nscd"
|
||||||
|
if _, err := sys.Stat(nscd); !errors.Is(err, fs.ErrNotExist) {
|
||||||
|
conf.Filesystem = append(conf.Filesystem, &hst.FilesystemConfig{Dst: nscd, Src: hst.SourceTmpfs})
|
||||||
|
}
|
||||||
|
|
||||||
config.Container = conf
|
config.Container = conf
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +266,7 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
{
|
{
|
||||||
var uid, gid int
|
var uid, gid int
|
||||||
var err error
|
var err error
|
||||||
seal.container, seal.env, err = newContainer(config.Container, sys, &uid, &gid)
|
seal.container, seal.env, err = newContainer(config.Container, sys, seal.id.String(), &uid, &gid)
|
||||||
seal.waitDelay = config.Container.WaitDelay
|
seal.waitDelay = config.Container.WaitDelay
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hlog.WrapErrSuffix(err,
|
return hlog.WrapErrSuffix(err,
|
||||||
@ -305,18 +289,6 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !config.Container.AutoEtc {
|
|
||||||
if config.Container.Etc != "" {
|
|
||||||
seal.container.Bind(config.Container.Etc, "/etc", 0)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
etcPath := config.Container.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
|
// inner XDG_RUNTIME_DIR default formatting of `/run/user/%d` as mapped uid
|
||||||
innerRuntimeDir := path.Join("/run/user", mapuid.String())
|
innerRuntimeDir := path.Join("/run/user", mapuid.String())
|
||||||
seal.env[xdgRuntimeDir] = innerRuntimeDir
|
seal.env[xdgRuntimeDir] = innerRuntimeDir
|
||||||
@ -506,6 +478,9 @@ func (seal *outcome) finalise(ctx context.Context, sys sys.State, config *hst.Co
|
|||||||
seal.container.Tmpfs(dest, 1<<13, 0755)
|
seal.container.Tmpfs(dest, 1<<13, 0755)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mount root read-only as the final setup Op
|
||||||
|
seal.container.Remount("/", syscall.MS_RDONLY)
|
||||||
|
|
||||||
// append ExtraPerms last
|
// append ExtraPerms last
|
||||||
for _, p := range config.ExtraPerms {
|
for _, p := range config.ExtraPerms {
|
||||||
if p == nil {
|
if p == nil {
|
||||||
|
@ -175,7 +175,6 @@ in
|
|||||||
++ optionals app.useCommonPaths cfg.commonPaths
|
++ optionals app.useCommonPaths cfg.commonPaths
|
||||||
++ app.extraPaths;
|
++ app.extraPaths;
|
||||||
auto_etc = true;
|
auto_etc = true;
|
||||||
cover = [ "/var/run/nscd" ];
|
|
||||||
|
|
||||||
symlink = [
|
symlink = [
|
||||||
[
|
[
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
wayland-scanner,
|
wayland-scanner,
|
||||||
xorg,
|
xorg,
|
||||||
|
|
||||||
# for planterette
|
# for hpkg
|
||||||
zstd,
|
zstd,
|
||||||
gnutar,
|
gnutar,
|
||||||
coreutils,
|
coreutils,
|
||||||
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
buildGoModule rec {
|
buildGoModule rec {
|
||||||
pname = "hakurei";
|
pname = "hakurei";
|
||||||
version = "0.1.2";
|
version = "0.1.3";
|
||||||
|
|
||||||
srcFiltered = builtins.path {
|
srcFiltered = builtins.path {
|
||||||
name = "${pname}-src";
|
name = "${pname}-src";
|
||||||
@ -116,7 +116,7 @@ buildGoModule rec {
|
|||||||
makeBinaryWrapper "$out/libexec/hakurei" "$out/bin/hakurei" \
|
makeBinaryWrapper "$out/libexec/hakurei" "$out/bin/hakurei" \
|
||||||
--inherit-argv0 --prefix PATH : ${lib.makeBinPath appPackages}
|
--inherit-argv0 --prefix PATH : ${lib.makeBinPath appPackages}
|
||||||
|
|
||||||
makeBinaryWrapper "$out/libexec/planterette" "$out/bin/planterette" \
|
makeBinaryWrapper "$out/libexec/hpkg" "$out/bin/hpkg" \
|
||||||
--inherit-argv0 --prefix PATH : ${
|
--inherit-argv0 --prefix PATH : ${
|
||||||
lib.makeBinPath (
|
lib.makeBinPath (
|
||||||
appPackages
|
appPackages
|
||||||
|
@ -82,13 +82,18 @@
|
|||||||
jack.enable = true;
|
jack.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtualisation.qemu.options = [
|
virtualisation = {
|
||||||
# Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch:
|
# Hopefully reduces spurious test failures:
|
||||||
"-vga none -device virtio-gpu-pci"
|
memorySize = 4096;
|
||||||
|
|
||||||
# Increase Go test compiler performance:
|
qemu.options = [
|
||||||
"-smp 8"
|
# Need to switch to a different GPU driver than the default one (-vga std) so that Sway can launch:
|
||||||
];
|
"-vga none -device virtio-gpu-pci"
|
||||||
|
|
||||||
|
# Increase Go test compiler performance:
|
||||||
|
"-smp 8"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
environment.hakurei = {
|
environment.hakurei = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -23,17 +23,21 @@ let
|
|||||||
;
|
;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
importTestCase =
|
||||||
|
path:
|
||||||
|
import path {
|
||||||
|
inherit
|
||||||
|
fs
|
||||||
|
ent
|
||||||
|
ignore
|
||||||
|
system
|
||||||
|
;
|
||||||
|
};
|
||||||
|
|
||||||
callTestCase =
|
callTestCase =
|
||||||
path: identity:
|
path: identity:
|
||||||
let
|
let
|
||||||
tc = import path {
|
tc = importTestCase path;
|
||||||
inherit
|
|
||||||
fs
|
|
||||||
ent
|
|
||||||
ignore
|
|
||||||
system
|
|
||||||
;
|
|
||||||
};
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
name = "check-sandbox-${tc.name}";
|
name = "check-sandbox-${tc.name}";
|
||||||
@ -61,9 +65,13 @@ let
|
|||||||
testCaseName = name: "cat.gensokyo.hakurei.test." + name;
|
testCaseName = name: "cat.gensokyo.hakurei.test." + name;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
${testCaseName "preset"} = callTestCase ./preset.nix 1;
|
apps = {
|
||||||
${testCaseName "tty"} = callTestCase ./tty.nix 2;
|
${testCaseName "preset"} = callTestCase ./preset.nix 1;
|
||||||
${testCaseName "mapuid"} = callTestCase ./mapuid.nix 3;
|
${testCaseName "tty"} = callTestCase ./tty.nix 2;
|
||||||
${testCaseName "device"} = callTestCase ./device.nix 4;
|
${testCaseName "mapuid"} = callTestCase ./mapuid.nix 3;
|
||||||
${testCaseName "pdlike"} = callTestCase ./pdlike.nix 5;
|
${testCaseName "device"} = callTestCase ./device.nix 4;
|
||||||
|
${testCaseName "pdlike"} = callTestCase ./pdlike.nix 5;
|
||||||
|
};
|
||||||
|
|
||||||
|
pd = importTestCase ./pd.nix;
|
||||||
}
|
}
|
||||||
|
@ -195,15 +195,14 @@ in
|
|||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
run = fs "800001ed" { nscd = fs "800001ed" { } null; } null;
|
|
||||||
cache = fs "800001ed" { private = fs "800001c0" null null; } null;
|
cache = fs "800001ed" { private = fs "800001c0" null null; } null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
mount = [
|
||||||
(ent "/sysroot" "/" "rw,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
|
(ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000004,gid=1000004")
|
||||||
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
||||||
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000004,gid=1000004")
|
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000004,gid=1000004")
|
||||||
(ent "/" "/dev" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/" "/dev" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
|
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
|
||||||
(ent "/" "/dev/shm" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore)
|
(ent "/" "/dev/shm" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore)
|
||||||
@ -220,7 +219,7 @@ in
|
|||||||
(ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/cache" "/var/cache" "rw,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 "/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=1000004,gid=1000004")
|
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000004,gid=1000004")
|
||||||
(ent "/tmp/hakurei.1000/runtime/4" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/runtime/4" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/tmp/hakurei.1000/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/tmpdir/4" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/lib/hakurei/u0/a4" "/var/lib/hakurei/u0/a4" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
@ -229,7 +228,6 @@ in
|
|||||||
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/" "/var/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8k,mode=755,uid=1000004,gid=1000004")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
seccomp = true;
|
seccomp = true;
|
||||||
|
@ -221,15 +221,14 @@ in
|
|||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
run = fs "800001ed" { nscd = fs "800001ed" { } null; } null;
|
|
||||||
cache = fs "800001ed" { private = fs "800001c0" null null; } null;
|
cache = fs "800001ed" { private = fs "800001c0" null null; } null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
mount = [
|
||||||
(ent "/sysroot" "/" "rw,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
|
(ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000003,gid=1000003")
|
||||||
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
||||||
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000003,gid=1000003")
|
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000003,gid=1000003")
|
||||||
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000003,gid=1000003")
|
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000003,gid=1000003")
|
||||||
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
@ -250,7 +249,7 @@ in
|
|||||||
(ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/cache" "/var/cache" "rw,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 "/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" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000003,gid=1000003")
|
||||||
(ent "/tmp/hakurei.1000/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/runtime/3" "/run/user/1000" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/tmp/hakurei.1000/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/tmpdir/3" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/lib/hakurei/u0/a3" "/var/lib/hakurei/u0/a3" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
@ -259,7 +258,6 @@ in
|
|||||||
(ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/1000/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/1000/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
(ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/1000/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/" "/var/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8k,mode=755,uid=1000003,gid=1000003")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
seccomp = true;
|
seccomp = true;
|
||||||
|
198
test/sandbox/case/pd.nix
Normal file
198
test/sandbox/case/pd.nix
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
{
|
||||||
|
fs,
|
||||||
|
ent,
|
||||||
|
ignore,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
# 0, PresetExt | PresetDenyDevel
|
||||||
|
expectedFilter = {
|
||||||
|
x86_64-linux = "c698b081ff957afe17a6d94374537d37f2a63f6f9dd75da7546542407a9e32476ebda3312ba7785d7f618542bcfaf27ca27dcc2dddba852069d28bcfe8cad39a";
|
||||||
|
aarch64-linux = "433ce9b911282d6dcc8029319fb79b816b60d5a795ec8fc94344dd027614d68f023166a91bb881faaeeedd26e3d89474e141e5a69a97e93b8984ca8f14999980";
|
||||||
|
};
|
||||||
|
|
||||||
|
want = {
|
||||||
|
env = [
|
||||||
|
"HOME=/var/lib/hakurei/u0/a0"
|
||||||
|
"SHELL=/run/current-system/sw/bin/bash"
|
||||||
|
"TERM=linux"
|
||||||
|
"USER=u0_a0"
|
||||||
|
"XDG_RUNTIME_DIR=/run/user/65534"
|
||||||
|
"XDG_SESSION_CLASS=user"
|
||||||
|
"XDG_SESSION_TYPE=tty"
|
||||||
|
];
|
||||||
|
|
||||||
|
fs = fs "dead" {
|
||||||
|
".hakurei" = fs "800001ed" { } null;
|
||||||
|
bin = fs "800001ed" { sh = fs "80001ff" null null; } null;
|
||||||
|
dev = fs "800001ed" {
|
||||||
|
console = fs "4200190" null null;
|
||||||
|
core = fs "80001ff" null null;
|
||||||
|
fd = fs "80001ff" null null;
|
||||||
|
full = fs "42001b6" null null;
|
||||||
|
kvm = fs "42001b6" null null;
|
||||||
|
mqueue = fs "801001ff" { } null;
|
||||||
|
null = fs "42001b6" null "";
|
||||||
|
ptmx = fs "80001ff" null null;
|
||||||
|
pts = fs "800001ed" { ptmx = fs "42001b6" null null; } null;
|
||||||
|
random = fs "42001b6" null null;
|
||||||
|
shm = fs "800001ed" { } null;
|
||||||
|
stderr = fs "80001ff" null null;
|
||||||
|
stdin = fs "80001ff" null null;
|
||||||
|
stdout = fs "80001ff" null null;
|
||||||
|
tty = fs "42001b6" null null;
|
||||||
|
urandom = fs "42001b6" null null;
|
||||||
|
zero = fs "42001b6" null null;
|
||||||
|
} 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;
|
||||||
|
"alsa" = fs "80001ff" null null;
|
||||||
|
"bash_logout" = fs "80001ff" null null;
|
||||||
|
"bashrc" = fs "80001ff" null null;
|
||||||
|
"binfmt.d" = fs "80001ff" null null;
|
||||||
|
"dbus-1" = fs "80001ff" null null;
|
||||||
|
"default" = fs "80001ff" null null;
|
||||||
|
"dhcpcd.exit-hook" = fs "80001ff" null null;
|
||||||
|
"fonts" = fs "80001ff" null null;
|
||||||
|
"fstab" = fs "80001ff" null null;
|
||||||
|
"hsurc" = fs "80001ff" null null;
|
||||||
|
"fuse.conf" = fs "80001ff" null null;
|
||||||
|
"group" = fs "180" null "hakurei:x:65534:\n";
|
||||||
|
"host.conf" = fs "80001ff" null null;
|
||||||
|
"hostname" = fs "80001ff" null null;
|
||||||
|
"hosts" = fs "80001ff" null null;
|
||||||
|
"inputrc" = fs "80001ff" null null;
|
||||||
|
"issue" = fs "80001ff" null null;
|
||||||
|
"kbd" = fs "80001ff" null null;
|
||||||
|
"locale.conf" = fs "80001ff" null null;
|
||||||
|
"login.defs" = fs "80001ff" null null;
|
||||||
|
"lsb-release" = fs "80001ff" null null;
|
||||||
|
"lvm" = fs "80001ff" null null;
|
||||||
|
"machine-id" = fs "80001ff" null null;
|
||||||
|
"man_db.conf" = fs "80001ff" null null;
|
||||||
|
"modprobe.d" = fs "80001ff" null null;
|
||||||
|
"modules-load.d" = fs "80001ff" null null;
|
||||||
|
"mtab" = fs "80001ff" null null;
|
||||||
|
"nanorc" = fs "80001ff" null null;
|
||||||
|
"netgroup" = fs "80001ff" null null;
|
||||||
|
"nix" = fs "80001ff" null null;
|
||||||
|
"nixos" = fs "80001ff" null null;
|
||||||
|
"nscd.conf" = fs "80001ff" null null;
|
||||||
|
"nsswitch.conf" = fs "80001ff" null null;
|
||||||
|
"os-release" = fs "80001ff" null null;
|
||||||
|
"pam" = fs "80001ff" null null;
|
||||||
|
"pam.d" = fs "80001ff" null null;
|
||||||
|
"passwd" = fs "180" null "u0_a0:x:65534:65534:Hakurei:/var/lib/hakurei/u0/a0:/run/current-system/sw/bin/bash\n";
|
||||||
|
"pipewire" = fs "80001ff" null null;
|
||||||
|
"pki" = fs "80001ff" null null;
|
||||||
|
"polkit-1" = fs "80001ff" null null;
|
||||||
|
"profile" = fs "80001ff" null null;
|
||||||
|
"protocols" = fs "80001ff" null null;
|
||||||
|
"resolv.conf" = fs "80001ff" null null;
|
||||||
|
"resolvconf.conf" = fs "80001ff" null null;
|
||||||
|
"rpc" = fs "80001ff" null null;
|
||||||
|
"services" = fs "80001ff" null null;
|
||||||
|
"set-environment" = fs "80001ff" null null;
|
||||||
|
"shadow" = fs "80001ff" null null;
|
||||||
|
"shells" = fs "80001ff" null null;
|
||||||
|
"ssh" = fs "80001ff" null null;
|
||||||
|
"ssl" = fs "80001ff" null null;
|
||||||
|
"static" = fs "80001ff" null null;
|
||||||
|
"subgid" = fs "80001ff" null null;
|
||||||
|
"subuid" = fs "80001ff" null null;
|
||||||
|
"sudoers" = fs "80001ff" null null;
|
||||||
|
"sway" = fs "80001ff" null null;
|
||||||
|
"sysctl.d" = fs "80001ff" null null;
|
||||||
|
"systemd" = fs "80001ff" null null;
|
||||||
|
"terminfo" = fs "80001ff" null null;
|
||||||
|
"tmpfiles.d" = fs "80001ff" null null;
|
||||||
|
"udev" = fs "80001ff" null null;
|
||||||
|
"vconsole.conf" = fs "80001ff" null null;
|
||||||
|
"xdg" = fs "80001ff" null null;
|
||||||
|
"zoneinfo" = fs "80001ff" null null;
|
||||||
|
} null;
|
||||||
|
home = fs "800001ed" { alice = fs "800001c0" null null; } null;
|
||||||
|
lib64 = fs "800001ed" { "ld-linux-x86-64.so.2" = fs "80001ff" null null; } null;
|
||||||
|
"lost+found" = fs "800001c0" null null;
|
||||||
|
nix = fs "800001ed" {
|
||||||
|
".ro-store" = fs "801001fd" null null;
|
||||||
|
".rw-store" = fs "800001ed" null null;
|
||||||
|
store = fs "801001fd" null null;
|
||||||
|
var = fs "800001ed" {
|
||||||
|
log = fs "800001ed" null null;
|
||||||
|
nix = fs "800001ed" null null;
|
||||||
|
} null;
|
||||||
|
} null;
|
||||||
|
proc = fs "8000016d" null null;
|
||||||
|
root = fs "800001c0" null null;
|
||||||
|
run = fs "800001ed" null null;
|
||||||
|
srv = fs "800001ed" { } null;
|
||||||
|
sys = fs "8000016d" null null;
|
||||||
|
tmp = fs "800001f8" { } null;
|
||||||
|
usr = fs "800001ed" { bin = fs "800001ed" { env = fs "80001ff" null null; } null; } null;
|
||||||
|
var = fs "800001ed" null null;
|
||||||
|
} null;
|
||||||
|
|
||||||
|
mount = [
|
||||||
|
(ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
|
||||||
|
(ent "/bin" "/bin" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/home" "/home" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/lib64" "/lib64" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/lost+found" "/lost+found" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/nix" "/nix" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/" "/nix/.ro-store" "rw,nosuid,nodev,relatime" "9p" "nix-store" ignore)
|
||||||
|
(ent "/" "/nix/.rw-store" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,mode=755")
|
||||||
|
(ent "/" "/nix/store" "rw,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on")
|
||||||
|
(ent "/" "/nix/store" "ro,nosuid,nodev,relatime" "overlay" "overlay" "rw,lowerdir=/mnt-root/nix/.ro-store,upperdir=/mnt-root/nix/.rw-store/upper,workdir=/mnt-root/nix/.rw-store/work,uuid=on")
|
||||||
|
(ent "/root" "/root" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/" "/run" "rw,nosuid,nodev" "tmpfs" "tmpfs" ignore)
|
||||||
|
(ent "/" "/run/keys" "rw,nosuid,nodev,relatime" "ramfs" "ramfs" "rw,mode=750")
|
||||||
|
(ent "/" "/run/credentials/systemd-journald.service" "ro,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "tmpfs" "rw,size=1024k,nr_inodes=1024,mode=700,noswap")
|
||||||
|
(ent "/" "/run/wrappers" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
|
(ent "/" "/run/credentials/getty@tty1.service" "ro,nosuid,nodev,noexec,relatime,nosymfollow" "tmpfs" "tmpfs" "rw,size=1024k,nr_inodes=1024,mode=700,noswap")
|
||||||
|
(ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
|
(ent "/srv" "/srv" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/" "/sys" "rw,nosuid,nodev,noexec,relatime" "sysfs" "sysfs" "rw")
|
||||||
|
(ent "/" "/sys/kernel/security" "rw,nosuid,nodev,noexec,relatime" "securityfs" "securityfs" "rw")
|
||||||
|
(ent "/../../.." "/sys/fs/cgroup" "rw,nosuid,nodev,noexec,relatime" "cgroup2" "cgroup2" "rw,nsdelegate,memory_recursiveprot")
|
||||||
|
(ent "/" "/sys/fs/pstore" "rw,nosuid,nodev,noexec,relatime" "pstore" "pstore" "rw")
|
||||||
|
(ent "/" "/sys/fs/bpf" "rw,nosuid,nodev,noexec,relatime" "bpf" "bpf" "rw,mode=700")
|
||||||
|
# systemd race: tracefs debugfs configfs fusectl
|
||||||
|
(ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
|
||||||
|
(ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
|
||||||
|
(ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
|
||||||
|
(ent "/" ignore "rw,nosuid,nodev,noexec,relatime" ignore ignore "rw")
|
||||||
|
(ent "/usr" "/usr" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/var" "/var" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
||||||
|
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000000,gid=1000000")
|
||||||
|
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000000,gid=1000000")
|
||||||
|
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/full" "/dev/full" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/random" "/dev/random" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/urandom" "/dev/urandom" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/tty" "/dev/tty" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/" "/dev/pts" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,mode=620,ptmxmode=666")
|
||||||
|
(ent ignore "/dev/console" "rw,nosuid,noexec,relatime" "devpts" "devpts" "rw,gid=3,mode=620,ptmxmode=666")
|
||||||
|
(ent "/" "/dev/mqueue" "rw,nosuid,nodev,noexec,relatime" "mqueue" "mqueue" "rw")
|
||||||
|
(ent "/kvm" "/dev/kvm" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
|
(ent "/" "/run/nscd" "ro,nosuid,nodev,relatime" "tmpfs" "readonly" "ro,mode=755,uid=1000000,gid=1000000")
|
||||||
|
(ent "/" "/run/user/1000" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
|
||||||
|
(ent "/" "/run/dbus" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=8k,mode=755,uid=1000000,gid=1000000")
|
||||||
|
(ent "/etc" ignore "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000000,gid=1000000")
|
||||||
|
(ent "/tmp/hakurei.1000/runtime/0" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/tmp/hakurei.1000/tmpdir/0" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent "/var/lib/hakurei/u0/a0" "/var/lib/hakurei/u0/a0" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
|
(ent ignore "/etc/passwd" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
|
||||||
|
(ent ignore "/etc/group" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000000,gid=1000000")
|
||||||
|
];
|
||||||
|
|
||||||
|
seccomp = true;
|
||||||
|
};
|
||||||
|
}
|
@ -222,14 +222,13 @@ in
|
|||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
run = fs "800001ed" { nscd = fs "800001ed" { } null; } null;
|
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
mount = [
|
||||||
(ent "/sysroot" "/" "rw,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
|
(ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000005,gid=1000005")
|
||||||
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
||||||
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000005,gid=1000005")
|
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000005,gid=1000005")
|
||||||
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000005,gid=1000005")
|
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000005,gid=1000005")
|
||||||
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
@ -250,7 +249,7 @@ in
|
|||||||
(ent "/devices" "/sys/devices" "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 "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/etc" ignore "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=1000005,gid=1000005")
|
(ent "/" "/run/user" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000005,gid=1000005")
|
||||||
(ent "/tmp/hakurei.1000/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/runtime/5" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/tmp/hakurei.1000/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/tmpdir/5" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/lib/hakurei/u0/a5" "/var/lib/hakurei/u0/a5" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
@ -259,7 +258,6 @@ in
|
|||||||
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/" "/var/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8k,mode=755,uid=1000005,gid=1000005")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
seccomp = true;
|
seccomp = true;
|
||||||
|
@ -221,14 +221,13 @@ in
|
|||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
run = fs "800001ed" { nscd = fs "800001ed" { } null; } null;
|
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
mount = [
|
||||||
(ent "/sysroot" "/" "rw,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
|
(ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000001,gid=1000001")
|
||||||
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
||||||
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000001,gid=1000001")
|
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000001,gid=1000001")
|
||||||
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000001,gid=1000001")
|
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000001,gid=1000001")
|
||||||
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
@ -248,7 +247,7 @@ in
|
|||||||
(ent "/devices" "/sys/devices" "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 "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/etc" ignore "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" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000001,gid=1000001")
|
||||||
(ent "/tmp/hakurei.1000/runtime/1" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/runtime/1" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/tmp/hakurei.1000/tmpdir/1" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/tmpdir/1" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/lib/hakurei/u0/a1" "/var/lib/hakurei/u0/a1" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
@ -257,7 +256,6 @@ in
|
|||||||
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/" "/var/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8k,mode=755,uid=1000001,gid=1000001")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
seccomp = true;
|
seccomp = true;
|
||||||
|
@ -222,15 +222,14 @@ in
|
|||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
run = fs "800001ed" { nscd = fs "800001ed" { } null; } null;
|
|
||||||
cache = fs "800001ed" { private = fs "800001c0" null null; } null;
|
cache = fs "800001ed" { private = fs "800001c0" null null; } null;
|
||||||
} null;
|
} null;
|
||||||
} null;
|
} null;
|
||||||
|
|
||||||
mount = [
|
mount = [
|
||||||
(ent "/sysroot" "/" "rw,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
|
(ent "/sysroot" "/" "ro,nosuid,nodev,relatime" "tmpfs" "rootfs" "rw,uid=1000002,gid=1000002")
|
||||||
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
(ent "/" "/proc" "rw,nosuid,nodev,noexec,relatime" "proc" "proc" "rw")
|
||||||
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=4k,mode=755,uid=1000002,gid=1000002")
|
(ent "/" "/.hakurei" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000002,gid=1000002")
|
||||||
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000002,gid=1000002")
|
(ent "/" "/dev" "rw,nosuid,nodev,relatime" "tmpfs" "devtmpfs" "rw,mode=755,uid=1000002,gid=1000002")
|
||||||
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/null" "/dev/null" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/zero" "/dev/zero" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
@ -252,7 +251,7 @@ in
|
|||||||
(ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
(ent "/dri" "/dev/dri" "rw,nosuid" "devtmpfs" "devtmpfs" ignore)
|
||||||
(ent "/var/cache" "/var/cache" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/cache" "/var/cache" "rw,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 "/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" "rw,nosuid,nodev,relatime" "tmpfs" "ephemeral" "rw,size=4k,mode=755,uid=1000002,gid=1000002")
|
||||||
(ent "/tmp/hakurei.1000/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/runtime/2" "/run/user/65534" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/tmp/hakurei.1000/tmpdir/2" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/tmp/hakurei.1000/tmpdir/2" "/tmp" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent "/var/lib/hakurei/u0/a2" "/var/lib/hakurei/u0/a2" "rw,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
@ -261,7 +260,6 @@ in
|
|||||||
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/wayland-0" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
(ent ignore "/run/user/65534/pulse/native" "ro,nosuid,nodev,relatime" "tmpfs" "tmpfs" ignore)
|
||||||
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
(ent ignore "/run/user/65534/bus" "ro,nosuid,nodev,relatime" "ext4" "/dev/disk/by-label/nixos" "rw")
|
||||||
(ent "/" "/var/run/nscd" "rw,nosuid,nodev,relatime" "tmpfs" "tmpfs" "rw,size=8k,mode=755,uid=1000002,gid=1000002")
|
|
||||||
];
|
];
|
||||||
|
|
||||||
seccomp = true;
|
seccomp = true;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
testProgram = pkgs.callPackage ./tool/package.nix { inherit (config.environment.hakurei.package) version; };
|
testProgram = pkgs.callPackage ./tool/package.nix { inherit (config.environment.hakurei.package) version; };
|
||||||
|
testCases = import ./case pkgs.system lib testProgram;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
users.users = {
|
users.users = {
|
||||||
@ -26,6 +27,13 @@ in
|
|||||||
systemPackages = [
|
systemPackages = [
|
||||||
# For checking seccomp outcome:
|
# For checking seccomp outcome:
|
||||||
testProgram
|
testProgram
|
||||||
|
|
||||||
|
# For checking pd outcome:
|
||||||
|
(pkgs.writeShellScriptBin "check-sandbox-pd" ''
|
||||||
|
hakurei -v run hakurei-test \
|
||||||
|
-t ${toString (builtins.toFile "hakurei-pd-want.json" (builtins.toJSON testCases.pd.want))} \
|
||||||
|
-s ${testCases.pd.expectedFilter.${pkgs.system}} "$@"
|
||||||
|
'')
|
||||||
];
|
];
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
@ -75,6 +83,6 @@ in
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
apps = import ./case pkgs.system lib testProgram;
|
inherit (testCases) apps;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -58,12 +58,13 @@ print(machine.fail("sudo -u alice -i hakurei run umount -R /dev"))
|
|||||||
check_offset = 0
|
check_offset = 0
|
||||||
def check_sandbox(name):
|
def check_sandbox(name):
|
||||||
global check_offset
|
global check_offset
|
||||||
check_offset += 1
|
|
||||||
swaymsg(f"exec script /dev/null -E always -qec check-sandbox-{name}")
|
swaymsg(f"exec script /dev/null -E always -qec check-sandbox-{name}")
|
||||||
machine.wait_for_file(f"/tmp/hakurei.1000/tmpdir/{check_offset}/sandbox-ok", timeout=15)
|
machine.wait_for_file(f"/tmp/hakurei.1000/tmpdir/{check_offset}/sandbox-ok", timeout=15)
|
||||||
check_filter(check_offset, name, "hakurei-test")
|
check_filter(check_offset, name, "hakurei-test")
|
||||||
|
check_offset += 1
|
||||||
|
|
||||||
|
|
||||||
|
check_sandbox("pd")
|
||||||
check_sandbox("preset")
|
check_sandbox("preset")
|
||||||
check_sandbox("tty")
|
check_sandbox("tty")
|
||||||
check_sandbox("mapuid")
|
check_sandbox("mapuid")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user