From bf17c3e80daa975ac15d6146964ca294327d8fd9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 18 Jan 2022 23:43:35 -0800 Subject: filesystem: add back the mountsByPath map Add back the mountsByPath map, which indexes all Mounts by mountpoint. This is needed again. To avoid confusion, also rename two local variables named mountsByPath. mountsByPath won't contain nil entries, so also make AllFilesystems() use it instead of mountsByDevice. This shouldn't change its behavior. Update https://github.com/google/fscrypt/issues/339 --- filesystem/mountpoint_test.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'filesystem/mountpoint_test.go') diff --git a/filesystem/mountpoint_test.go b/filesystem/mountpoint_test.go index 6600d87..a4688ed 100644 --- a/filesystem/mountpoint_test.go +++ b/filesystem/mountpoint_test.go @@ -90,6 +90,12 @@ func TestLoadMountInfoBasic(t *testing.T) { if mnt.ReadOnly { t.Error("Wrong readonly flag") } + if len(mountsByPath) != 1 { + t.Error("mountsByPath doesn't contain exactly one entry") + } + if mountsByPath[mnt.Path] != mnt { + t.Error("mountsByPath doesn't contain the correct entry") + } } // Test that Mount.Device is set to the mountpoint's source device if -- cgit v1.3 From c2fb96c60d7678110bca14ff0a213243bd97cb08 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Tue, 18 Jan 2022 23:43:35 -0800 Subject: filesystem: fall back to path-only links if UUID cannot be determined This is needed to allow creating protector links to btrfs filesystems. Update https://github.com/google/fscrypt/issues/339 --- filesystem/mountpoint.go | 13 ++++++++++--- filesystem/mountpoint_test.go | 44 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) (limited to 'filesystem/mountpoint_test.go') diff --git a/filesystem/mountpoint.go b/filesystem/mountpoint.go index 20a8568..182cafa 100644 --- a/filesystem/mountpoint.go +++ b/filesystem/mountpoint.go @@ -545,12 +545,19 @@ func (mnt *Mount) getFilesystemUUID() (string, error) { } // makeLink creates the contents of a link file which will point to the given -// filesystem. This will be a string of the form "UUID=\nPATH=\n". -// An error is returned if the filesystem's UUID cannot be determined. +// filesystem. This will normally be a string of the form +// "UUID=\nPATH=\n". If the UUID cannot be determined, the UUID +// portion will be omitted. func makeLink(mnt *Mount) (string, error) { uuid, err := mnt.getFilesystemUUID() if err != nil { - return "", &ErrMakeLink{mnt, err} + // The UUID could not be determined. This happens for btrfs + // filesystems, as the device number found via + // /dev/disk/by-uuid/* for btrfs filesystems differs from the + // actual device number of the mounted filesystem. Just rely + // entirely on the fallback to mountpoint path. + log.Print(err) + return fmt.Sprintf("%s=%s\n", pathToken, mnt.Path), nil } return fmt.Sprintf("%s=%s\n%s=%s\n", uuidToken, uuid, pathToken, mnt.Path), nil } diff --git a/filesystem/mountpoint_test.go b/filesystem/mountpoint_test.go index a4688ed..749e5e3 100644 --- a/filesystem/mountpoint_test.go +++ b/filesystem/mountpoint_test.go @@ -411,6 +411,40 @@ func TestGetMountFromLink(t *testing.T) { } } +// Test that makeLink() is including the expected information in links. +func TestMakeLink(t *testing.T) { + mnt, err := getTestMount(t) + if err != nil { + t.Skip(err) + } + link, err := makeLink(mnt) + if err != nil { + t.Fatal(err) + } + + // Normally, both UUID and PATH should be included. + if !strings.Contains(link, "UUID=") { + t.Fatal("Link doesn't contain UUID") + } + if !strings.Contains(link, "PATH=") { + t.Fatal("Link doesn't contain PATH") + } + + // Without a valid device number, only PATH should be included. + mntCopy := *mnt + mntCopy.DeviceNumber = 0 + link, err = makeLink(&mntCopy) + if err != nil { + t.Fatal(err) + } + if strings.Contains(link, "UUID=") { + t.Fatal("Link shouldn't contain UUID") + } + if !strings.Contains(link, "PATH=") { + t.Fatal("Link doesn't contain PATH") + } +} + // Test that old filesystem links that contain a UUID only still work. func TestGetMountFromLegacyLink(t *testing.T) { mnt, err := getTestMount(t) @@ -456,6 +490,16 @@ func TestGetMountFromLinkFallback(t *testing.T) { t.Fatal("Link doesn't point to the same Mount") } + // only PATH given at all (should succeed) + link = fmt.Sprintf("PATH=%s\n", mnt.Path) + linkedMnt, err = getMountFromLink(link) + if err != nil { + t.Fatal(err) + } + if linkedMnt != mnt { + t.Fatal("Link doesn't point to the same Mount") + } + // only UUID valid (should succeed) link = fmt.Sprintf("UUID=%s\nPATH=%s\n", goodUUID, badPath) if linkedMnt, err = getMountFromLink(link); err != nil { -- cgit v1.3