aboutsummaryrefslogtreecommitdiff
path: root/filesystem/filesystem.go
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-10-29 00:33:54 -0700
committerEric Biggers <ebiggers@google.com>2019-10-30 09:21:59 -0700
commitdbafdbaa9b0767f71affaf15fb8c626f64e27122 (patch)
tree4a00cc9611161d0157f1932b2339ae89c3eee20b /filesystem/filesystem.go
parentfe58e7236a3285e172733aeab0b136bec968ac4d (diff)
filesystem: handle bind mounts properly
Currently, fscrypt treats bind mounts as separate filesystems. This is broken because fscrypt will look for a directory's encryption policy in different places depending on which mount it's accessed through. This forces users to create an fscrypt metadata directory at every bind mount, and to copy fscrypt metadata around between mounts. Fix this by storing fscrypt metadata only at the root of the filesystem. To accomplish this: - Make mountsByDevice store only a single Mount per filesystem, rather than multiple. For this Mount, choose a mount of the full filesystem if available, preferably a read-write mount. If the filesystem has only bind mounts, store a nil entry in mountsByDevice so we can show a proper error message later. - Change FindMount() and GetMount() to look up the Mount by device number rather than by path, so that they don't return different Mounts depending on which path is used. - Change AllFilesystems() to not return bind mounts. - Due to the above changes, the mountsByPath map is no longer needed outside of loadMountInfo(). So make it a local variable there. Resolves https://github.com/google/fscrypt/issues/59
Diffstat (limited to 'filesystem/filesystem.go')
-rw-r--r--filesystem/filesystem.go22
1 files changed, 11 insertions, 11 deletions
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index c37962a..9bae72b 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -70,6 +70,9 @@ var (
// DeviceNumber - Device number of the filesystem. This is set even if
// Device isn't, since all filesystems have a device
// number assigned by the kernel, even pseudo-filesystems.
+// BindMnt - True if this mount is not for the full filesystem but
+// rather is only for a subtree.
+// ReadOnly - True if this is a read-only mount
//
// In order to use a Mount to store fscrypt metadata, some directories must be
// setup first. Specifically, the directories created look like:
@@ -96,6 +99,8 @@ type Mount struct {
FilesystemType string
Device string
DeviceNumber DeviceNumber
+ BindMnt bool
+ ReadOnly bool
}
// PathSorter allows mounts to be sorted by Path.
@@ -437,21 +442,16 @@ func (m *Mount) GetProtector(descriptor string) (*Mount, *metadata.ProtectorData
return nil, nil, m.err(err)
}
- // As the link could refer to multiple filesystems, we check each one
- // for valid metadata.
- mnts, err := getMountsFromLink(string(link))
+ linkedMnt, err := getMountFromLink(string(link))
if err != nil {
return nil, nil, m.err(err)
}
-
- for _, mnt := range mnts {
- if data, err := mnt.GetRegularProtector(descriptor); err != nil {
- log.Print(err)
- } else {
- return mnt, data, nil
- }
+ data, err := linkedMnt.GetRegularProtector(descriptor)
+ if err != nil {
+ log.Print(err)
+ return nil, nil, m.err(errors.Wrapf(ErrLinkExpired, "protector %s", descriptor))
}
- return nil, nil, m.err(errors.Wrapf(ErrLinkExpired, "protector %s", descriptor))
+ return linkedMnt, data, nil
}
// RemoveProtector deletes the protector metadata (or a link to another