diff --git a/container/autoroot_test.go b/container/autoroot_test.go index fed1ab1..8c72b78 100644 --- a/container/autoroot_test.go +++ b/container/autoroot_test.go @@ -5,6 +5,7 @@ import ( "os" "testing" + "hakurei.app/container/bits" "hakurei.app/container/check" "hakurei.app/container/stub" ) @@ -20,14 +21,14 @@ func TestAutoRootOp(t *testing.T) { checkOpBehaviour(t, []opBehaviourTestCase{ {"readdir", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, []stub.Call{ call("readdir", stub.ExpectArgs{"/"}, stubDir(), stub.UniqueError(2)), }, stub.UniqueError(2), nil, nil}, {"early", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, []stub.Call{ call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil), @@ -36,7 +37,7 @@ func TestAutoRootOp(t *testing.T) { {"apply", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, []stub.Call{ call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil), @@ -57,7 +58,7 @@ func TestAutoRootOp(t *testing.T) { {"success pd", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, []stub.Call{ call("readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil), @@ -124,10 +125,10 @@ func TestAutoRootOp(t *testing.T) { }) checkOpsBuilder(t, []opsBuilderTestCase{ - {"pd", new(Ops).Root(check.MustAbs("/"), BindWritable), Ops{ + {"pd", new(Ops).Root(check.MustAbs("/"), bits.BindWritable), Ops{ &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, }}, }) @@ -137,42 +138,42 @@ func TestAutoRootOp(t *testing.T) { {"internal ne", &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, resolved: []*BindMountOp{new(BindMountOp)}, }, true}, {"flags differs", &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable | BindDevice, + Flags: bits.BindWritable | bits.BindDevice, }, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, false}, {"host differs", &AutoRootOp{ Host: check.MustAbs("/tmp/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, false}, {"equals", &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, true}, }) checkOpMeta(t, []opMetaTestCase{ {"root", &AutoRootOp{ Host: check.MustAbs("/"), - Flags: BindWritable, + Flags: bits.BindWritable, }, "setting up", `auto root "/" flags 0x2`}, }) } diff --git a/container/bits/bits.go b/container/bits/bits.go new file mode 100644 index 0000000..7aa2e44 --- /dev/null +++ b/container/bits/bits.go @@ -0,0 +1,13 @@ +// Package bits contains constants for configuring the container. +package bits + +const ( + // BindOptional skips nonexistent host paths. + BindOptional = 1 << iota + // BindWritable mounts filesystem read-write. + BindWritable + // BindDevice allows access to devices (special files) on this filesystem. + BindDevice + // BindEnsure attempts to create the host path if it does not exist. + BindEnsure +) diff --git a/container/init_test.go b/container/init_test.go index de700db..1db8174 100644 --- a/container/init_test.go +++ b/container/init_test.go @@ -350,7 +350,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(nil, nil, BindDevice), + Ops: new(Ops).Bind(nil, nil, bits.BindDevice), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -388,7 +388,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -427,7 +427,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -466,7 +466,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -506,7 +506,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -547,7 +547,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -589,7 +589,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -632,7 +632,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -676,7 +676,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -721,7 +721,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -767,7 +767,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -822,7 +822,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -877,7 +877,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -933,7 +933,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -990,7 +990,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1049,7 +1049,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1109,7 +1109,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1170,7 +1170,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1232,7 +1232,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1295,7 +1295,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1359,7 +1359,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1424,7 +1424,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1490,7 +1490,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1564,7 +1564,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1671,7 +1671,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1779,7 +1779,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, @@ -1889,7 +1889,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 24, Gid: 1 << 47, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, @@ -2003,7 +2003,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 24, Gid: 1 << 47, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, @@ -2103,7 +2103,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 24, Gid: 1 << 47, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, @@ -2194,7 +2194,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 24, Gid: 1 << 47, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, @@ -2287,7 +2287,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 24, Gid: 1 << 47, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, @@ -2387,7 +2387,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 24, Gid: 1 << 47, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, @@ -2523,7 +2523,7 @@ func TestInitEntrypoint(t *testing.T) { Uid: 1 << 32, Gid: 1 << 31, Hostname: "hakurei-check", - Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), BindDevice).Proc(check.MustAbs("/proc/")), + Ops: new(Ops).Bind(check.MustAbs("/"), check.MustAbs("/"), bits.BindDevice).Proc(check.MustAbs("/proc/")), SeccompRules: make([]seccomp.NativeRule, 0), SeccompPresets: bits.PresetStrict, RetainSession: true, diff --git a/container/initbind.go b/container/initbind.go index 0cb2e2f..54f0012 100644 --- a/container/initbind.go +++ b/container/initbind.go @@ -6,6 +6,7 @@ import ( "os" "syscall" + "hakurei.app/container/bits" "hakurei.app/container/check" ) @@ -25,32 +26,21 @@ type BindMountOp struct { Flags int } -const ( - // BindOptional skips nonexistent host paths. - BindOptional = 1 << iota - // BindWritable mounts filesystem read-write. - BindWritable - // BindDevice allows access to devices (special files) on this filesystem. - BindDevice - // BindEnsure attempts to create the host path if it does not exist. - BindEnsure -) - func (b *BindMountOp) Valid() bool { return b != nil && b.Source != nil && b.Target != nil && - b.Flags&(BindOptional|BindEnsure) != (BindOptional|BindEnsure) + b.Flags&(bits.BindOptional|bits.BindEnsure) != (bits.BindOptional|bits.BindEnsure) } func (b *BindMountOp) early(_ *setupState, k syscallDispatcher) error { - if b.Flags&BindEnsure != 0 { + if b.Flags&bits.BindEnsure != 0 { if err := k.mkdirAll(b.Source.String(), 0700); err != nil { return err } } if pathname, err := k.evalSymlinks(b.Source.String()); err != nil { - if os.IsNotExist(err) && b.Flags&BindOptional != 0 { + if os.IsNotExist(err) && b.Flags&bits.BindOptional != 0 { // leave sourceFinal as nil return nil } @@ -63,7 +53,7 @@ func (b *BindMountOp) early(_ *setupState, k syscallDispatcher) error { func (b *BindMountOp) apply(state *setupState, k syscallDispatcher) error { if b.sourceFinal == nil { - if b.Flags&BindOptional == 0 { + if b.Flags&bits.BindOptional == 0 { // unreachable return OpStateError("bind") } @@ -86,10 +76,10 @@ func (b *BindMountOp) apply(state *setupState, k syscallDispatcher) error { } var flags uintptr = syscall.MS_REC - if b.Flags&BindWritable == 0 { + if b.Flags&bits.BindWritable == 0 { flags |= syscall.MS_RDONLY } - if b.Flags&BindDevice == 0 { + if b.Flags&bits.BindDevice == 0 { flags |= syscall.MS_NODEV } diff --git a/container/initbind_test.go b/container/initbind_test.go index 5e0c37e..41a1d97 100644 --- a/container/initbind_test.go +++ b/container/initbind_test.go @@ -6,6 +6,7 @@ import ( "syscall" "testing" + "hakurei.app/container/bits" "hakurei.app/container/check" "hakurei.app/container/stub" ) @@ -22,7 +23,7 @@ func TestBindMountOp(t *testing.T) { {"skip optional", new(Params), &BindMountOp{ Source: check.MustAbs("/bin/"), Target: check.MustAbs("/bin/"), - Flags: BindOptional, + Flags: bits.BindOptional, }, []stub.Call{ call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT), }, nil, nil, nil}, @@ -30,7 +31,7 @@ func TestBindMountOp(t *testing.T) { {"success optional", new(Params), &BindMountOp{ Source: check.MustAbs("/bin/"), Target: check.MustAbs("/bin/"), - Flags: BindOptional, + Flags: bits.BindOptional, }, []stub.Call{ call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil), }, nil, []stub.Call{ @@ -43,7 +44,7 @@ func TestBindMountOp(t *testing.T) { {"ensureFile device", new(Params), &BindMountOp{ Source: check.MustAbs("/dev/null"), Target: check.MustAbs("/dev/null"), - Flags: BindWritable | BindDevice, + Flags: bits.BindWritable | bits.BindDevice, }, []stub.Call{ call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil), }, nil, []stub.Call{ @@ -54,7 +55,7 @@ func TestBindMountOp(t *testing.T) { {"mkdirAll ensure", new(Params), &BindMountOp{ Source: check.MustAbs("/bin/"), Target: check.MustAbs("/bin/"), - Flags: BindEnsure, + Flags: bits.BindEnsure, }, []stub.Call{ call("mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, stub.UniqueError(4)), }, stub.UniqueError(4), nil, nil}, @@ -62,7 +63,7 @@ func TestBindMountOp(t *testing.T) { {"success ensure", new(Params), &BindMountOp{ Source: check.MustAbs("/bin/"), Target: check.MustAbs("/usr/bin/"), - Flags: BindEnsure, + Flags: bits.BindEnsure, }, []stub.Call{ call("mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, nil), call("evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil), @@ -76,7 +77,7 @@ func TestBindMountOp(t *testing.T) { {"success device ro", new(Params), &BindMountOp{ Source: check.MustAbs("/dev/null"), Target: check.MustAbs("/dev/null"), - Flags: BindDevice, + Flags: bits.BindDevice, }, []stub.Call{ call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil), }, nil, []stub.Call{ @@ -89,7 +90,7 @@ func TestBindMountOp(t *testing.T) { {"success device", new(Params), &BindMountOp{ Source: check.MustAbs("/dev/null"), Target: check.MustAbs("/dev/null"), - Flags: BindWritable | BindDevice, + Flags: bits.BindWritable | bits.BindDevice, }, []stub.Call{ call("evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil), }, nil, []stub.Call{ @@ -176,7 +177,7 @@ func TestBindMountOp(t *testing.T) { {"zero", new(BindMountOp), false}, {"nil source", &BindMountOp{Target: check.MustAbs("/")}, false}, {"nil target", &BindMountOp{Source: check.MustAbs("/")}, false}, - {"flag optional ensure", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/"), Flags: BindOptional | BindEnsure}, false}, + {"flag optional ensure", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/"), Flags: bits.BindOptional | bits.BindEnsure}, false}, {"valid", &BindMountOp{Source: check.MustAbs("/"), Target: check.MustAbs("/")}, true}, }) @@ -211,7 +212,7 @@ func TestBindMountOp(t *testing.T) { }, &BindMountOp{ Source: check.MustAbs("/etc/"), Target: check.MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"), - Flags: BindOptional, + Flags: bits.BindOptional, }, false}, {"source differs", &BindMountOp{ @@ -250,7 +251,7 @@ func TestBindMountOp(t *testing.T) { {"hostdev", &BindMountOp{ Source: check.MustAbs("/dev/"), Target: check.MustAbs("/dev/"), - Flags: BindWritable | BindDevice, + Flags: bits.BindWritable | bits.BindDevice, }, "mounting", `"/dev/" flags 0x6`}, }) } diff --git a/hst/fsbind.go b/hst/fsbind.go index 8b7b5fe..f94e467 100644 --- a/hst/fsbind.go +++ b/hst/fsbind.go @@ -4,7 +4,7 @@ import ( "encoding/gob" "strings" - "hakurei.app/container" + "hakurei.app/container/bits" "hakurei.app/container/check" "hakurei.app/container/fhs" ) @@ -96,16 +96,16 @@ func (b *FSBind) Apply(z *ApplyState) { } var flags int if b.Write { - flags |= container.BindWritable + flags |= bits.BindWritable } if b.Device { - flags |= container.BindDevice | container.BindWritable + flags |= bits.BindDevice | bits.BindWritable } if b.Ensure { - flags |= container.BindEnsure + flags |= bits.BindEnsure } if b.Optional { - flags |= container.BindOptional + flags |= bits.BindOptional } switch { diff --git a/hst/fsbind_test.go b/hst/fsbind_test.go index 4b9cc19..62de240 100644 --- a/hst/fsbind_test.go +++ b/hst/fsbind_test.go @@ -4,6 +4,7 @@ import ( "testing" "hakurei.app/container" + "hakurei.app/container/bits" "hakurei.app/hst" ) @@ -21,7 +22,7 @@ func TestFSBind(t *testing.T) { }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/dev"), Target: m("/dev"), - Flags: container.BindWritable | container.BindDevice | container.BindOptional, + Flags: bits.BindWritable | bits.BindDevice | bits.BindOptional, }}, m("/dev"), ms("/mnt/dev"), "d+/mnt/dev:/dev"}, @@ -33,7 +34,7 @@ func TestFSBind(t *testing.T) { }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/dev"), Target: m("/dev"), - Flags: container.BindWritable | container.BindDevice | container.BindEnsure, + Flags: bits.BindWritable | bits.BindDevice | bits.BindEnsure, }}, m("/dev"), ms("/mnt/dev"), "d-/mnt/dev:/dev"}, @@ -45,7 +46,7 @@ func TestFSBind(t *testing.T) { }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/dev"), Target: m("/dev"), - Flags: container.BindWritable | container.BindDevice, + Flags: bits.BindWritable | bits.BindDevice, }}, m("/dev"), ms("/mnt/dev"), "d*/mnt/dev:/dev"}, @@ -56,7 +57,7 @@ func TestFSBind(t *testing.T) { }, true, container.Ops{&container.BindMountOp{ Source: m("/mnt/tmp"), Target: m("/tmp"), - Flags: container.BindWritable, + Flags: bits.BindWritable, }}, m("/tmp"), ms("/mnt/tmp"), "w*/mnt/tmp:/tmp"}, @@ -95,7 +96,7 @@ func TestFSBind(t *testing.T) { Special: true, }, true, container.Ops{&container.AutoRootOp{ Host: m("/"), - Flags: container.BindWritable, + Flags: bits.BindWritable, }}, m("/"), ms("/"), "autoroot:w"}, {"autoroot silly", &hst.FSBind{ @@ -105,7 +106,7 @@ func TestFSBind(t *testing.T) { Special: true, }, true, container.Ops{&container.AutoRootOp{ Host: m("/etc"), - Flags: container.BindWritable, + Flags: bits.BindWritable, }}, m("/"), ms("/etc"), "autoroot:w:/etc"}, {"autoetc", &hst.FSBind{ diff --git a/internal/app/app_test.go b/internal/app/app_test.go index e0f9305..90c4579 100644 --- a/internal/app/app_test.go +++ b/internal/app/app_test.go @@ -93,20 +93,20 @@ func TestApp(t *testing.T) { "XDG_SESSION_TYPE=tty", }, Ops: new(container.Ops). - Root(m("/"), container.BindWritable). + Root(m("/"), bits.BindWritable). Proc(m("/proc/")). Tmpfs(hst.AbsTmp, 4096, 0755). DevWritable(m("/dev/"), true). Tmpfs(m("/dev/shm"), 0, 01777). - Bind(m("/dev/kvm"), m("/dev/kvm"), container.BindWritable|container.BindDevice|container.BindOptional). + Bind(m("/dev/kvm"), m("/dev/kvm"), bits.BindWritable|bits.BindDevice|bits.BindOptional). Etc(m("/etc/"), "4a450b6596d7bc15bd01780eb9a607ac"). Tmpfs(m("/run/user/1971"), 8192, 0755). Tmpfs(m("/run/nscd"), 8192, 0755). Tmpfs(m("/run/dbus"), 8192, 0755). Remount(m("/dev/"), syscall.MS_RDONLY). Tmpfs(m("/run/user/"), 4096, 0755). - Bind(m("/tmp/hakurei.0/runtime/0"), m("/run/user/65534"), container.BindWritable). - Bind(m("/tmp/hakurei.0/tmpdir/0"), m("/tmp/"), container.BindWritable). + Bind(m("/tmp/hakurei.0/runtime/0"), m("/run/user/65534"), bits.BindWritable). + Bind(m("/tmp/hakurei.0/tmpdir/0"), m("/tmp/"), bits.BindWritable). Place(m("/etc/passwd"), []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")). Place(m("/etc/group"), []byte("hakurei:x:65534:\n")). Remount(m("/"), syscall.MS_RDONLY), @@ -260,21 +260,21 @@ func TestApp(t *testing.T) { "XDG_SESSION_TYPE=tty", }, Ops: new(container.Ops). - Root(m("/"), container.BindWritable). + Root(m("/"), bits.BindWritable). Proc(m("/proc/")). Tmpfs(hst.AbsTmp, 4096, 0755). DevWritable(m("/dev/"), true). Tmpfs(m("/dev/shm"), 0, 01777). - Bind(m("/dev/dri"), m("/dev/dri"), container.BindWritable|container.BindDevice|container.BindOptional). - Bind(m("/dev/kvm"), m("/dev/kvm"), container.BindWritable|container.BindDevice|container.BindOptional). + Bind(m("/dev/dri"), m("/dev/dri"), bits.BindWritable|bits.BindDevice|bits.BindOptional). + Bind(m("/dev/kvm"), m("/dev/kvm"), bits.BindWritable|bits.BindDevice|bits.BindOptional). Etc(m("/etc/"), "ebf083d1b175911782d413369b64ce7c"). Tmpfs(m("/run/user/1971"), 8192, 0755). Tmpfs(m("/run/nscd"), 8192, 0755). Tmpfs(m("/run/dbus"), 8192, 0755). Remount(m("/dev/"), syscall.MS_RDONLY). Tmpfs(m("/run/user/"), 4096, 0755). - Bind(m("/tmp/hakurei.0/runtime/9"), m("/run/user/65534"), container.BindWritable). - Bind(m("/tmp/hakurei.0/tmpdir/9"), m("/tmp/"), container.BindWritable). + Bind(m("/tmp/hakurei.0/runtime/9"), m("/run/user/65534"), bits.BindWritable). + Bind(m("/tmp/hakurei.0/tmpdir/9"), m("/tmp/"), bits.BindWritable). Place(m("/etc/passwd"), []byte("chronos:x:65534:65534:Hakurei:/home/chronos:/run/current-system/sw/bin/zsh\n")). Place(m("/etc/group"), []byte("hakurei:x:65534:\n")). Bind(m("/tmp/hakurei.0/ebf083d1b175911782d413369b64ce7c/wayland"), m("/run/user/65534/wayland-0"), 0). @@ -412,19 +412,19 @@ func TestApp(t *testing.T) { Bind(m("/usr/bin/"), m("/usr/bin/"), 0). Bind(m("/nix/store"), m("/nix/store"), 0). Bind(m("/run/current-system"), m("/run/current-system"), 0). - Bind(m("/sys/block"), m("/sys/block"), container.BindOptional). - Bind(m("/sys/bus"), m("/sys/bus"), container.BindOptional). - Bind(m("/sys/class"), m("/sys/class"), container.BindOptional). - Bind(m("/sys/dev"), m("/sys/dev"), container.BindOptional). - Bind(m("/sys/devices"), m("/sys/devices"), container.BindOptional). + Bind(m("/sys/block"), m("/sys/block"), bits.BindOptional). + Bind(m("/sys/bus"), m("/sys/bus"), bits.BindOptional). + Bind(m("/sys/class"), m("/sys/class"), bits.BindOptional). + Bind(m("/sys/dev"), m("/sys/dev"), bits.BindOptional). + Bind(m("/sys/devices"), m("/sys/devices"), bits.BindOptional). Bind(m("/run/opengl-driver"), m("/run/opengl-driver"), 0). - Bind(m("/dev/dri"), m("/dev/dri"), container.BindDevice|container.BindWritable|container.BindOptional). + Bind(m("/dev/dri"), m("/dev/dri"), bits.BindDevice|bits.BindWritable|bits.BindOptional). Etc(m("/etc/"), "8e2c76b066dabe574cf073bdb46eb5c1"). - Bind(m("/var/lib/persist/module/hakurei/0/1"), m("/var/lib/persist/module/hakurei/0/1"), container.BindWritable|container.BindEnsure). + Bind(m("/var/lib/persist/module/hakurei/0/1"), m("/var/lib/persist/module/hakurei/0/1"), bits.BindWritable|bits.BindEnsure). Remount(m("/dev/"), syscall.MS_RDONLY). Tmpfs(m("/run/user/"), 4096, 0755). - Bind(m("/tmp/hakurei.0/runtime/1"), m("/run/user/1971"), container.BindWritable). - Bind(m("/tmp/hakurei.0/tmpdir/1"), m("/tmp/"), container.BindWritable). + Bind(m("/tmp/hakurei.0/runtime/1"), m("/run/user/1971"), bits.BindWritable). + Bind(m("/tmp/hakurei.0/tmpdir/1"), m("/tmp/"), bits.BindWritable). Place(m("/etc/passwd"), []byte("u0_a1:x:1971:100:Hakurei:/var/lib/persist/module/hakurei/0/1:/run/current-system/sw/bin/zsh\n")). Place(m("/etc/group"), []byte("hakurei:x:100:\n")). Bind(m("/run/user/1971/wayland-0"), m("/run/user/1971/wayland-0"), 0). diff --git a/internal/app/spcontainer.go b/internal/app/spcontainer.go index aed6d92..96afecb 100644 --- a/internal/app/spcontainer.go +++ b/internal/app/spcontainer.go @@ -104,7 +104,7 @@ func (s *spParamsOp) toContainer(state *outcomeStateParams) error { if !state.Container.Device { state.params.DevWritable(fhs.AbsDev, true) } else { - state.params.Bind(fhs.AbsDev, fhs.AbsDev, container.BindWritable|container.BindDevice) + state.params.Bind(fhs.AbsDev, fhs.AbsDev, bits.BindWritable|bits.BindDevice) } // /dev is mounted readonly later on, this prevents /dev/shm from going readonly with it state.params.Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777) diff --git a/internal/app/spruntime.go b/internal/app/spruntime.go index be18885..d327003 100644 --- a/internal/app/spruntime.go +++ b/internal/app/spruntime.go @@ -1,7 +1,7 @@ package app import ( - "hakurei.app/container" + "hakurei.app/container/bits" "hakurei.app/container/check" "hakurei.app/container/fhs" "hakurei.app/hst" @@ -35,7 +35,7 @@ func (s spRuntimeOp) toContainer(state *outcomeStateParams) error { _, runtimeDirInst := s.commonPaths(state.outcomeState) state.params.Tmpfs(fhs.AbsRunUser, 1<<12, 0755) - state.params.Bind(runtimeDirInst, state.runtimeDir, container.BindWritable) + state.params.Bind(runtimeDirInst, state.runtimeDir, bits.BindWritable) return nil } diff --git a/internal/app/sptmpdir.go b/internal/app/sptmpdir.go index 265e51c..4cc0c7d 100644 --- a/internal/app/sptmpdir.go +++ b/internal/app/sptmpdir.go @@ -1,7 +1,7 @@ package app import ( - "hakurei.app/container" + "hakurei.app/container/bits" "hakurei.app/container/check" "hakurei.app/container/fhs" "hakurei.app/hst" @@ -24,7 +24,7 @@ func (s spTmpdirOp) toSystem(state *outcomeStateSys, _ *hst.Config) error { func (s spTmpdirOp) toContainer(state *outcomeStateParams) error { // mount inner /tmp from share so it shares persistence and storage behaviour of host /tmp _, tmpdirInst := s.commonPaths(state.outcomeState) - state.params.Bind(tmpdirInst, fhs.AbsTmp, container.BindWritable) + state.params.Bind(tmpdirInst, fhs.AbsTmp, bits.BindWritable) return nil } diff --git a/system/dbus/proc.go b/system/dbus/proc.go index a4c9300..005b914 100644 --- a/system/dbus/proc.go +++ b/system/dbus/proc.go @@ -114,7 +114,7 @@ func (p *Proxy) Start() error { check.SortAbs(sockDirPaths) sockDirPaths = check.CompactAbs(sockDirPaths) for _, name := range sockDirPaths { - z.Bind(name, name, container.BindWritable) + z.Bind(name, name, bits.BindWritable) } // xdg-dbus-proxy bin path