package rootstate import "testing" func TestPlan14PersistentIdentityBootLocalNumbers(t *testing.T) { p := FileIdentity{Boot: "boot-one", Filesystem: "fs", Handle: "handle", MountRoot: "/", MountPoint: "/", MountNamespace: "mnt:[1]", Device: 1, Inode: 2, Mount: 3, UID: 4, GID: 5, Mode: 0100000} if !p.Same(p) { t.Fatal("same identity refused") } unknown := FileIdentity{Device: 1, Inode: 2} if unknown.Same(unknown) { t.Fatal("numeric identity without a boot acquired authority") } next := p next.Boot = "boot-two" next.Device = 7 next.Mount = 8 if !p.Same(next) { t.Fatal("cross-boot device numbers used as identity") } next.Boot = p.Boot if p.Same(next) { t.Fatal("same-boot replacement accepted") } for _, field := range []string{"filesystem", "handle", "mount", "inode", "uid", "gid", "type", "mode", "absent"} { next = p next.Boot = "boot-two" switch field { case "filesystem": next.Filesystem = "other" case "handle": next.Handle = "other" case "mount": next.MountPoint = "other" case "inode": next.Inode++ case "uid": next.UID++ case "gid": next.GID++ case "type": next.Mode ^= 0040000 case "mode": next.Mode++ case "absent": next.Boot = "" } if p.Same(next) { t.Fatal("substitution accepted", field) } } } func TestPlan14PersistentDeviceIdentity(t *testing.T) { a := FileIdentity{Device: 259, Inode: 7, Boot: "before", Filesystem: "ext4:fs", Handle: "abcd", HandleType: 1, Mount: 64, MountRoot: "/", MountPoint: "/", MountNamespace: "mnt:[1]", Mode: 0100644} b := a b.Boot, b.Device, b.Mount = "after", 513, 127 if !a.Same(b) { t.Fatal("device renumbering rejected persistent identity") } for _, mutate := range []func(*FileIdentity){ func(b *FileIdentity) { b.Boot = a.Boot }, func(b *FileIdentity) { b.Handle = "reused-inode" }, func(b *FileIdentity) { b.Filesystem = "other" }, func(b *FileIdentity) { b.MountRoot = "/replacement" }, func(b *FileIdentity) { b.MountPoint = "/etc" }, func(b *FileIdentity) { b.UID = 1000 }, func(b *FileIdentity) { b.Mode = 0100664 }, } { bad := b mutate(&bad) if a.Same(bad) { t.Fatal("substitution accepted", bad) } } clone := a clone.MountNamespace = "mnt:[2]" clone.Mount++ if !a.Same(clone) { t.Fatal("root namespace clone lost persistent identity") } clone.MountPoint = "/etc" if a.Same(clone) { t.Fatal("namespace clone hid substituted mount") } old := FileIdentity{Device: a.Device, Inode: a.Inode} if old.Same(a) || a.Same(old) { t.Fatal("historical identity acquired inferred proof") } }