aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-08-20 02:22:04 +0900
committerOphestra <cat@gensokyo.uk>2025-08-20 02:22:04 +0900
commite463faf6499fa537f6048857e10d123554112af6 (patch)
tree9493f0bb21a7d1edc8c7c0a922730b73957c6f5e
parent375acb476d36cac8e122ae8c45628bd8e7e0f0ca (diff)
container/initbind: check path equivalence by value
Same problem as autoroot, never updated the checks after integrating Absolute. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--container/initbind.go17
-rw-r--r--container/initbind_test.go63
2 files changed, 77 insertions, 3 deletions
diff --git a/container/initbind.go b/container/initbind.go
index 12db42d8..17cd9598 100644
--- a/container/initbind.go
+++ b/container/initbind.go
@@ -85,10 +85,21 @@ func (b *BindMountOp) apply(*setupState) error {
return hostProc.bindMount(source, target, flags, b.sourceFinal == b.Target)
}
-func (b *BindMountOp) Is(op Op) bool { vb, ok := op.(*BindMountOp); return ok && *b == *vb }
-func (*BindMountOp) prefix() string { return "mounting" }
+func (b *BindMountOp) Is(op Op) bool {
+ vb, ok := op.(*BindMountOp)
+ return ok && ((b == nil && vb == nil) || (b != nil && vb != nil &&
+ b.Source != nil && vb.Source != nil &&
+ b.Source.String() == vb.Source.String() &&
+ b.Target != nil && vb.Target != nil &&
+ b.Target.String() == vb.Target.String() &&
+ b.Flags == vb.Flags))
+}
+func (*BindMountOp) prefix() string { return "mounting" }
func (b *BindMountOp) String() string {
- if b.Source == b.Target {
+ if b.Source == nil || b.Target == nil {
+ return "<invalid>"
+ }
+ if b.Source.String() == b.Target.String() {
return fmt.Sprintf("%q flags %#x", b.Source, b.Flags)
}
return fmt.Sprintf("%q on %q flags %#x", b.Source, b.Target, b.Flags)
diff --git a/container/initbind_test.go b/container/initbind_test.go
new file mode 100644
index 00000000..dec9113a
--- /dev/null
+++ b/container/initbind_test.go
@@ -0,0 +1,63 @@
+package container
+
+import "testing"
+
+func TestBindMountOp(t *testing.T) {
+ checkOpsBuilder(t, []opsBuilderTestCase{
+ {"autoetc", new(Ops).Bind(
+ MustAbs("/etc/"),
+ MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ 0,
+ ), Ops{
+ &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ },
+ }},
+ })
+
+ checkOpIs(t, []opIsTestCase{
+ {"zero", new(BindMountOp), new(BindMountOp), false},
+
+ {"internal ne", &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ }, &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ sourceFinal: MustAbs("/etc/"),
+ }, true},
+
+ {"differs", &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ }, &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ Flags: BindOptional,
+ }, false},
+
+ {"equals", &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ }, &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ }, true},
+ })
+
+ checkOpMeta(t, []opMetaTestCase{
+ {"invalid", new(BindMountOp), "mounting", "<invalid>"},
+
+ {"autoetc", &BindMountOp{
+ Source: MustAbs("/etc/"),
+ Target: MustAbs("/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659"),
+ }, "mounting", `"/etc/" on "/etc/.host/048090b6ed8f9ebb10e275ff5d8c0659" flags 0x0`},
+
+ {"hostdev", &BindMountOp{
+ Source: MustAbs("/dev/"),
+ Target: MustAbs("/dev/"),
+ Flags: BindWritable | BindDevice,
+ }, "mounting", `"/dev/" flags 0x6`},
+ })
+}