aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2021-12-20 11:28:26 -0600
committerGitHub <noreply@github.com>2021-12-20 11:28:26 -0600
commit9a8ce15408edae0c92128fd36f50dafa81013266 (patch)
treeb8d89c0ee0a18aa38b0a5df1d06ab6037f8c2190
parent1014b61a6a054b5c82b2be82e13d8ce28befba45 (diff)
parentd0b9e2c995beb13c70a1549923df482ff773f09b (diff)
Merge pull request #332 from ebiggers/skip-irrelevant-filesystems
filesystem: avoid accessing irrelevant filesystems
-rw-r--r--cli-tests/t_not_supported.out4
-rwxr-xr-xcli-tests/t_not_supported.sh4
-rw-r--r--filesystem/filesystem.go49
-rw-r--r--filesystem/filesystem_test.go2
4 files changed, 52 insertions, 7 deletions
diff --git a/cli-tests/t_not_supported.out b/cli-tests/t_not_supported.out
index ecee56a..68e0897 100644
--- a/cli-tests/t_not_supported.out
+++ b/cli-tests/t_not_supported.out
@@ -1,8 +1,8 @@
# Mount tmpfs
-# Create fscrypt metadata on tmpfs
-Metadata directories created at "MNT/.fscrypt".
+# Try to create fscrypt metadata on tmpfs
+[ERROR] fscrypt setup: filesystem type tmpfs is not supported for fscrypt setup
# Try to encrypt a directory on tmpfs
[ERROR] fscrypt encrypt: This kernel doesn't support encryption on tmpfs
diff --git a/cli-tests/t_not_supported.sh b/cli-tests/t_not_supported.sh
index 53a096a..9ff90e1 100755
--- a/cli-tests/t_not_supported.sh
+++ b/cli-tests/t_not_supported.sh
@@ -9,8 +9,8 @@ _print_header "Mount tmpfs"
umount "$MNT"
mount tmpfs -t tmpfs -o size=128m "$MNT"
-_print_header "Create fscrypt metadata on tmpfs"
-fscrypt setup "$MNT"
+_print_header "Try to create fscrypt metadata on tmpfs"
+_expect_failure "fscrypt setup '$MNT'"
_print_header "Try to encrypt a directory on tmpfs"
mkdir "$MNT/dir"
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 456a4fc..0b30452 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -112,6 +112,17 @@ func (err *ErrNotSetup) Error() string {
return fmt.Sprintf("filesystem %s is not setup for use with fscrypt", err.Mount.Path)
}
+// ErrSetupNotSupported indicates that the given filesystem type is not
+// supported for fscrypt setup.
+type ErrSetupNotSupported struct {
+ Mount *Mount
+}
+
+func (err *ErrSetupNotSupported) Error() string {
+ return fmt.Sprintf("filesystem type %s is not supported for fscrypt setup",
+ err.Mount.FilesystemType)
+}
+
// ErrPolicyNotFound indicates that the policy metadata was not found.
type ErrPolicyNotFound struct {
Descriptor string
@@ -299,15 +310,46 @@ func (m *Mount) EncryptionSupportError(err error) error {
return err
}
-// CheckSupport returns an error if this filesystem does not support filesystem
-// encryption.
+// isFscryptSetupAllowed decides whether the given filesystem is allowed to be
+// set up for fscrypt, without actually accessing it. This basically checks
+// whether the filesystem type is one of the types that supports encryption, or
+// at least is in some stage of planning for encrption support in the future.
+//
+// We need this list so that we can skip filesystems that are irrelevant for
+// fscrypt without having to look for the fscrypt metadata directories on them,
+// which can trigger errors, long delays, or side effects on some filesystems.
+//
+// Unfortunately, this means that if a completely new filesystem adds encryption
+// support, then it will need to be manually added to this list. But it seems
+// to be a worthwhile tradeoff to avoid the above issues.
+func (m *Mount) isFscryptSetupAllowed() bool {
+ if m.Path == "/" {
+ // The root filesystem is always allowed, since it's where login
+ // protectors are stored.
+ return true
+ }
+ switch m.FilesystemType {
+ case "ext4", "f2fs", "ubifs", "btrfs", "ceph", "xfs":
+ return true
+ default:
+ return false
+ }
+}
+
+// CheckSupport returns an error if this filesystem does not support encryption.
func (m *Mount) CheckSupport() error {
+ if !m.isFscryptSetupAllowed() {
+ return &ErrEncryptionNotSupported{m}
+ }
return m.EncryptionSupportError(metadata.CheckSupport(m.Path))
}
// CheckSetup returns an error if all the fscrypt metadata directories do not
// exist. Will log any unexpected errors or incorrect permissions.
func (m *Mount) CheckSetup() error {
+ if !m.isFscryptSetupAllowed() {
+ return &ErrNotSetup{m}
+ }
// Run all the checks so we will always get all the warnings
baseGood := isDirCheckPerm(m.BaseDir(), basePermissions)
policyGood := isDirCheckPerm(m.PolicyDir(), dirPermissions)
@@ -345,6 +387,9 @@ func (m *Mount) Setup() error {
if m.CheckSetup() == nil {
return &ErrAlreadySetup{m}
}
+ if !m.isFscryptSetupAllowed() {
+ return &ErrSetupNotSupported{m}
+ }
// We build the directories under a temp Mount and then move into place.
temp, err := m.tempMount()
if err != nil {
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index 9b534bd..92726b2 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -324,7 +324,7 @@ func getTwoSetupMounts(t *testing.T) (realMnt, fakeMnt *Mount, err error) {
if err = os.MkdirAll(fakeMountpoint, basePermissions); err != nil {
return
}
- fakeMnt = &Mount{Path: fakeMountpoint}
+ fakeMnt = &Mount{Path: fakeMountpoint, FilesystemType: realMnt.FilesystemType}
err = fakeMnt.Setup()
return
}