From e9919b0bfd00c7d228531ebafa410cbfdafcb2e3 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:06 -0700 Subject: actions/config: improve config file related errors ErrBadConfig: Fix backwards wrapping, include the bad config, and make it clear that this is an internal error. ErrBadConfigFile: Fix backwards wrapping, include the config file location, and adjust the suggestion slightly. ErrConfigFileExists: Include the config file location. ErrNoConfigFile: Include the config file location, and adjust the suggestion slightly. --- cmd/fscrypt/errors.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 8bda921..e7c025f 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -79,6 +79,12 @@ func getFullName(c *cli.Context) string { // getErrorSuggestions returns a string containing suggestions about how to fix // an error. If no suggestion is necessary or available, return empty string. func getErrorSuggestions(err error) string { + switch err.(type) { + case *actions.ErrBadConfigFile: + return `Either fix this file manually, or run "sudo fscrypt setup" to recreate it.` + case *actions.ErrNoConfigFile: + return `Run "sudo fscrypt setup" to create this file.` + } switch errors.Cause(err) { case filesystem.ErrNotSetup: return fmt.Sprintf(`Run "fscrypt setup %s" to use fscrypt on this filesystem.`, mountpointArg) @@ -117,10 +123,6 @@ func getErrorSuggestions(err error) string { return fmt.Sprintf(`v2 encryption policies are only supported by kernel version 5.4 and later. Either use a newer kernel, or change policy_version to 1 in %s.`, actions.ConfigFileLocation) - case actions.ErrBadConfigFile: - return `Run "sudo fscrypt setup" to recreate the file.` - case actions.ErrNoConfigFile: - return `Run "sudo fscrypt setup" to create the file.` case actions.ErrMissingPolicyMetadata: return `This file or directory has either been encrypted with another tool (such as e4crypt) or the corresponding -- cgit v1.2.3 From 37457cce5b0436493dba7cdac6e1af5f51d25f47 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: actions/protector: improve errors ErrProtectorName: Rename to ErrLoginProtectorName for clarity, and include the name and user. ErrMissingProtectorName: Include the correct protector source. ErrDuplicateName: Rename to ErrProtectorNameExists for clarity, and remove a level of wrapping by including the name directly. ErrDuplicateUID: Rename to ErrLoginProtectorExists for clarity, and remove a level of wrapping by including the user directly. --- cmd/fscrypt/errors.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index e7c025f..829a9d2 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -82,6 +82,10 @@ func getErrorSuggestions(err error) string { switch err.(type) { case *actions.ErrBadConfigFile: return `Either fix this file manually, or run "sudo fscrypt setup" to recreate it.` + case *actions.ErrLoginProtectorName: + return fmt.Sprintf("To fix this, don't specify the %s option.", shortDisplay(nameFlag)) + case *actions.ErrMissingProtectorName: + return fmt.Sprintf("Use %s to specify a protector name.", shortDisplay(nameFlag)) case *actions.ErrNoConfigFile: return `Run "sudo fscrypt setup" to create this file.` } @@ -131,8 +135,6 @@ func getErrorSuggestions(err error) string { return `The metadata for this encrypted directory is in an inconsistent state. This most likely means the filesystem metadata is corrupted.` - case actions.ErrMissingProtectorName: - return fmt.Sprintf("Use %s to specify a protector name.", shortDisplay(nameFlag)) case actions.ErrAccessDeniedPossiblyV2: return fmt.Sprintf(`This may be caused by the directory using a v2 encryption policy and the current kernel not supporting it. If -- cgit v1.2.3 From 209a2d1419ea575fd316bd9975fb63e40cce7a77 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: actions/policy: improve errors ErrMissingPolicyMetadata: Include the mount, directory path, and metadata path. Also move the explanation into actions/ since it doesn't refer to any CLI command. ErrPolicyMetadataMismatch: Include a lot more information. Also start checking for consistency of the policy key descriptors, not just the encryption options. Add a test for this. ErrDifferentFilesystem: Include the mountpoints. ErrOnlyProtector: Clarify the message and include the protector descriptor. ErrAlreadyProtected: ErrNotProtected: Include the policy and protector descriptors. ErrAccessDeniedPossiblyV2: Make it slightly clearer what failed. Also move the explanation into actions/ since it doesn't refer to any CLI command. --- cmd/fscrypt/errors.go | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 829a9d2..3e5beed 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -127,21 +127,6 @@ func getErrorSuggestions(err error) string { return fmt.Sprintf(`v2 encryption policies are only supported by kernel version 5.4 and later. Either use a newer kernel, or change policy_version to 1 in %s.`, actions.ConfigFileLocation) - case actions.ErrMissingPolicyMetadata: - return `This file or directory has either been encrypted with - another tool (such as e4crypt) or the corresponding - filesystem metadata has been deleted.` - case actions.ErrPolicyMetadataMismatch: - return `The metadata for this encrypted directory is in an - inconsistent state. This most likely means the filesystem - metadata is corrupted.` - case actions.ErrAccessDeniedPossiblyV2: - return fmt.Sprintf(`This may be caused by the directory using a v2 - encryption policy and the current kernel not supporting it. If - indeed the case, then this directory can only be used on kernel - v5.4 and later. You can create directories accessible on older - kernels by changing policy_version to 1 in %s.`, - actions.ConfigFileLocation) case ErrNoDestructiveOps: return fmt.Sprintf("Use %s to automatically run destructive operations.", shortDisplay(forceFlag)) case ErrSpecifyProtector: -- cgit v1.2.3 From 9383d4be92981a4c956c775479bb48b7eec9db79 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: crypto: improve errors ErrKeyLock: Rename to ErrMlockUlimit for clarity. ErrGetrandomFail: ErrKeyAlloc: ErrKeyFree: ErrNegativeLength: Replace these with one-off unnamed errors because these were all returned in only one place and were never checked for. Also these were all either wrapped backwards or discarded an underlying error, so fix that too. --- cmd/fscrypt/errors.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 3e5beed..f4f3ddb 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -92,7 +92,7 @@ func getErrorSuggestions(err error) string { switch errors.Cause(err) { case filesystem.ErrNotSetup: return fmt.Sprintf(`Run "fscrypt setup %s" to use fscrypt on this filesystem.`, mountpointArg) - case crypto.ErrKeyLock: + case crypto.ErrMlockUlimit: return `Too much memory was requested to be locked in RAM. The current limit for this user can be checked with "ulimit -l". The limit can be modified by either changing the -- cgit v1.2.3 From fb88d74f0335cdf8218bb8dfbaa03f23773318cf Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: keyring: improve errors ErrAccessUserKeyring: Include the user, and fix the backwards wrapping. ErrSessionUserKeyring: Include the user. ErrKeyAdd: ErrKeyRemove: ErrKeySearch: ErrLinkUserKeyring: Replace these with one-off unnamed errors because they are never checked for, and this makes it easier for the callers to provide better messages, e.g. fixing the backwards wrapping. --- cmd/fscrypt/errors.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index f4f3ddb..3f7150b 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -88,6 +88,14 @@ func getErrorSuggestions(err error) string { return fmt.Sprintf("Use %s to specify a protector name.", shortDisplay(nameFlag)) case *actions.ErrNoConfigFile: return `Run "sudo fscrypt setup" to create this file.` + case *keyring.ErrAccessUserKeyring: + return fmt.Sprintf(`You can only use %s to access the user + keyring of another user if you are running as root.`, + shortDisplay(userFlag)) + case *keyring.ErrSessionUserKeyring: + return `This is usually the result of a bad PAM configuration. + Either correct the problem in your PAM stack, enable + pam_keyinit.so, or run "keyctl link @u @s".` } switch errors.Cause(err) { case filesystem.ErrNotSetup: @@ -115,14 +123,6 @@ func getErrorSuggestions(err error) string { return `Directory couldn't be fully locked because other user(s) have unlocked it. If you want to force the directory to be locked, use 'sudo fscrypt lock --all-users DIR'.` - case keyring.ErrSessionUserKeying: - return `This is usually the result of a bad PAM configuration. - Either correct the problem in your PAM stack, enable - pam_keyinit.so, or run "keyctl link @u @s".` - case keyring.ErrAccessUserKeyring: - return fmt.Sprintf(`You can only use %s to access the user - keyring of another user if you are running as root.`, - shortDisplay(userFlag)) case keyring.ErrV2PoliciesUnsupported: return fmt.Sprintf(`v2 encryption policies are only supported by kernel version 5.4 and later. Either use a newer kernel, or change -- cgit v1.2.3 From fbc161a77962fe64e3caad80efb535d28d8c1f74 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: metadata: improve errors ErrBadOwners: Rename to ErrDirectoryNotOwned for clarity, move it from cmd/fscrypt/ to metadata/ where it better belongs, and improve the message. ErrEncrypted: Rename to ErrAlreadyEncrypted for clarity, and include the path. ErrNotEncrypted: Include the path. ErrBadEncryptionOptions: Include the path and bad options. ErrEncryptionNotSupported: ErrEncryptionNotEnabled: Don't wrap with "get encryption policy %s", in preparation for wrapping these with filesystem-level context instead. Also avoid mixing together the error handling for the "get policy" and "set policy" ioctls. Make it very clear how we're handling the errors from each ioctl. --- cmd/fscrypt/errors.go | 4 ---- 1 file changed, 4 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 3f7150b..6119862 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -57,7 +57,6 @@ var ( ErrMustBeRoot = errors.New("this command must be run as root") ErrPolicyUnlocked = errors.New("this file or directory is already unlocked") ErrPolicyLocked = errors.New("this file or directory is already locked") - ErrBadOwners = errors.New("you do not own this directory") ErrNotEmptyDir = errors.New("not an empty directory") ErrNotPassphrase = errors.New("protector does not use a passphrase") ErrUnknownUser = errors.New("unknown user") @@ -133,9 +132,6 @@ func getErrorSuggestions(err error) string { return fmt.Sprintf("Use %s to specify a protector.", shortDisplay(protectorFlag)) case ErrSpecifyKeyFile: return fmt.Sprintf("Use %s to specify a key file.", shortDisplay(keyFileFlag)) - case ErrBadOwners: - return `Encryption can only be setup on directories you own, - even if you have write permission for the directory.` case ErrNotEmptyDir: return `Encryption can only be setup on empty directories; files cannot be encrypted in-place. Instead, encrypt an empty -- cgit v1.2.3 From 66fb4c557644ba2c37951a7568c06c47a6c718a7 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: filesystem: improve errors Introduce filesystem.ErrEncryptionNotEnabled and filesystem.ErrEncryptionNotSupported which include the Mount as context, and translate the corresponding metadata/ errors into them. Then make these errors show much better suggestions. Also replace lots of other filesystem/ errors with either custom types or with unnamed one-off errors that include more context. Fix backwards wrapping in lots of cases. Finally, don't include the mountpoint in places where it's not useful, like OS-level errors that already include the path. --- cmd/fscrypt/errors.go | 93 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 82 insertions(+), 11 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 6119862..ef4ae64 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -30,6 +30,7 @@ import ( "github.com/pkg/errors" "github.com/urfave/cli" + "golang.org/x/sys/unix" "github.com/google/fscrypt/actions" "github.com/google/fscrypt/crypto" @@ -75,10 +76,69 @@ func getFullName(c *cli.Context) string { return c.App.HelpName } +func suggestEnablingEncryption(mnt *filesystem.Mount) string { + kconfig := "CONFIG_FS_ENCRYPTION=y" + switch mnt.FilesystemType { + case "ext4": + // Recommend running tune2fs -O encrypt. But be really careful; + // old kernels didn't support block_size != PAGE_SIZE, and old + // GRUB didn't support encryption. + var statfs unix.Statfs_t + if err := unix.Statfs(mnt.Path, &statfs); err != nil { + return "" + } + pagesize := int64(os.Getpagesize()) + if statfs.Bsize != pagesize && !util.IsKernelVersionAtLeast(5, 5) { + return fmt.Sprintf(`This filesystem uses a block size + (%d) other than the system page size (%d). Ext4 + encryption didn't support this case until kernel v5.5. + Do *not* enable encryption on this filesystem. Either + upgrade your kernel to v5.5 or later, or re-create this + filesystem using 'mkfs.ext4 -b %d -O encrypt %s' + (WARNING: that will erase all data on it).`, + statfs.Bsize, pagesize, pagesize, mnt.Device) + } + if !util.IsKernelVersionAtLeast(5, 1) { + kconfig = "CONFIG_EXT4_ENCRYPTION=y" + } + s := fmt.Sprintf(`To enable encryption support on this + filesystem, run: + + > sudo tune2fs -O encrypt %q + `, mnt.Device) + if _, err := os.Stat(filepath.Join(mnt.Path, "boot/grub")); err == nil { + s += ` + WARNING: you seem to have GRUB installed on this + filesystem. Before doing the above, make sure you are + using GRUB v2.04 or later; otherwise your system will + become unbootable. + ` + } + s += fmt.Sprintf(` + Also ensure that your kernel has %s. See the documentation for + more details.`, kconfig) + return s + case "f2fs": + if !util.IsKernelVersionAtLeast(5, 1) { + kconfig = "CONFIG_F2FS_FS_ENCRYPTION=y" + } + return fmt.Sprintf(`To enable encryption support on this + filesystem, you'll need to run: + + > sudo fsck.f2fs -O encrypt %q + + Also ensure that your kernel has %s. See the documentation for + more details.`, mnt.Device, kconfig) + default: + return `See the documentation for how to enable encryption + support on this filesystem.` + } +} + // getErrorSuggestions returns a string containing suggestions about how to fix // an error. If no suggestion is necessary or available, return empty string. func getErrorSuggestions(err error) string { - switch err.(type) { + switch e := err.(type) { case *actions.ErrBadConfigFile: return `Either fix this file manually, or run "sudo fscrypt setup" to recreate it.` case *actions.ErrLoginProtectorName: @@ -87,6 +147,27 @@ func getErrorSuggestions(err error) string { return fmt.Sprintf("Use %s to specify a protector name.", shortDisplay(nameFlag)) case *actions.ErrNoConfigFile: return `Run "sudo fscrypt setup" to create this file.` + case *filesystem.ErrEncryptionNotEnabled: + return suggestEnablingEncryption(e.Mount) + case *filesystem.ErrEncryptionNotSupported: + switch e.Mount.FilesystemType { + case "ext4": + if !util.IsKernelVersionAtLeast(4, 1) { + return "ext4 encryption requires kernel v4.1 or later." + } + case "f2fs": + if !util.IsKernelVersionAtLeast(4, 2) { + return "f2fs encryption requires kernel v4.2 or later." + } + case "ubifs": + if !util.IsKernelVersionAtLeast(4, 10) { + return "ubifs encryption requires kernel v4.10 or later." + } + } + return "" + case *filesystem.ErrNotSetup: + return fmt.Sprintf(`Run "sudo fscrypt setup %s" to use fscrypt + on this filesystem.`, e.Mount.Path) case *keyring.ErrAccessUserKeyring: return fmt.Sprintf(`You can only use %s to access the user keyring of another user if you are running as root.`, @@ -97,22 +178,12 @@ func getErrorSuggestions(err error) string { pam_keyinit.so, or run "keyctl link @u @s".` } switch errors.Cause(err) { - case filesystem.ErrNotSetup: - return fmt.Sprintf(`Run "fscrypt setup %s" to use fscrypt on this filesystem.`, mountpointArg) case crypto.ErrMlockUlimit: return `Too much memory was requested to be locked in RAM. The current limit for this user can be checked with "ulimit -l". The limit can be modified by either changing the "memlock" item in /etc/security/limits.conf or by changing the "LimitMEMLOCK" value in systemd.` - case metadata.ErrEncryptionNotSupported: - return `Encryption for this type of filesystem is not supported - on this kernel version.` - case metadata.ErrEncryptionNotEnabled: - return `Encryption is either disabled in the kernel config, or - needs to be enabled for this filesystem. See the - documentation on how to enable encryption on ext4 - systems (and the risks of doing so).` case keyring.ErrKeyFilesOpen: return `Directory was incompletely locked because some files are still open. These files remain accessible. Try killing -- cgit v1.2.3 From 197eb371697aff066947372d10732387454fd88a Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: cmd/fscrypt: remove ErrMaxPassphrase This isn't actually a valid error since crypto.NewKeyFromReader() handles re-allocating the buffer to a larger size if it fills up. --- cmd/fscrypt/errors.go | 1 - 1 file changed, 1 deletion(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index ef4ae64..4ce4504 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -47,7 +47,6 @@ const failureExitCode = 1 var ( ErrCanceled = errors.New("operation canceled") ErrNoDestructiveOps = errors.New("operation would be destructive") - ErrMaxPassphrase = util.SystemError("max passphrase length exceeded") ErrInvalidSource = errors.New("invalid source type") ErrPassphraseMismatch = errors.New("entered passphrases do not match") ErrSpecifyProtector = errors.New("multiple protectors available") -- cgit v1.2.3 From 181600d6327ed34a3f62eda0dd03a6d2ae49e5f9 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 9 May 2020 14:52:07 -0700 Subject: cmd/fscrypt: improve errors In checkEncryptable(), check whether the directory is already encrypted before checking whether it's empty. Also improve the error message for when a directory is nonempty. Finally, translate keyring.ErrKeyAddedByOtherUsers and keyring.ErrKeyFilesOpen into errors which include the directory. --- cmd/fscrypt/errors.go | 85 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 18 deletions(-) (limited to 'cmd/fscrypt/errors.go') diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go index 4ce4504..63ddaf4 100644 --- a/cmd/fscrypt/errors.go +++ b/cmd/fscrypt/errors.go @@ -55,9 +55,8 @@ var ( ErrKeyFileLength = errors.Errorf("key file must be %d bytes", metadata.InternalKeyLen) ErrAllLoadsFailed = errors.New("could not load any protectors") ErrMustBeRoot = errors.New("this command must be run as root") - ErrPolicyUnlocked = errors.New("this file or directory is already unlocked") - ErrPolicyLocked = errors.New("this file or directory is already locked") - ErrNotEmptyDir = errors.New("not an empty directory") + ErrDirAlreadyUnlocked = errors.New("this file or directory is already unlocked") + ErrDirAlreadyLocked = errors.New("this file or directory is already locked") ErrNotPassphrase = errors.New("protector does not use a passphrase") ErrUnknownUser = errors.New("unknown user") ErrDropCachesPerm = errors.New("inode cache can only be dropped as root") @@ -65,6 +64,38 @@ var ( ErrFsKeyringPerm = errors.New("root is required to add/remove v1 encryption policy keys to/from filesystem") ) +// ErrDirFilesOpen indicates that a directory can't be fully locked because +// files protected by the directory's policy are still open. +type ErrDirFilesOpen struct { + DirPath string +} + +func (err *ErrDirFilesOpen) Error() string { + return fmt.Sprintf(`Directory was incompletely locked because some files + are still open. These files remain accessible.`) +} + +// ErrDirUnlockedByOtherUsers indicates that a directory can't be locked because +// the directory's policy is still provisioned by other users. +type ErrDirUnlockedByOtherUsers struct { + DirPath string +} + +func (err *ErrDirUnlockedByOtherUsers) Error() string { + return fmt.Sprintf(`Directory %q couldn't be fully locked because other + user(s) have unlocked it.`, err.DirPath) +} + +// ErrDirNotEmpty indicates that a directory can't be encrypted because it's not +// empty. +type ErrDirNotEmpty struct { + DirPath string +} + +func (err *ErrDirNotEmpty) Error() string { + return fmt.Sprintf("Directory %q cannot be encrypted because it is non-empty.", err.DirPath) +} + var loadHelpText = fmt.Sprintf("You may need to mount a linked filesystem. Run with %s for more information.", shortDisplay(verboseFlag)) // getFullName returns the full name of the application or command being used. @@ -138,6 +169,37 @@ func suggestEnablingEncryption(mnt *filesystem.Mount) string { // an error. If no suggestion is necessary or available, return empty string. func getErrorSuggestions(err error) string { switch e := err.(type) { + case *ErrDirFilesOpen: + return fmt.Sprintf(`Try killing any processes using files in the + directory, for example using: + + > find %q -print0 | xargs -0 fuser -k + + Then re-run: + + > fscrypt lock %q`, e.DirPath, e.DirPath) + case *ErrDirNotEmpty: + dir := e.DirPath + newDir := dir + ".new" + return fmt.Sprintf(`Files cannot be encrypted in-place. Instead, + encrypt a new directory, copy the files into it, and securely + delete the original directory. For example: + + > mkdir %s + > fscrypt encrypt %s + > cp -a -T %s %s + > find %s -type f -print0 | xargs -0 shred -n1 --remove=unlink + > rm -rf %s + > mv %s %s + + Caution: due to the nature of modern storage devices and filesystems, + the original data may still be recoverable from disk. It's much better + to encrypt your files from the start.`, newDir, newDir, dir, newDir, dir, dir, newDir, dir) + case *ErrDirUnlockedByOtherUsers: + return fmt.Sprintf(`If you want to force the directory to be + locked, use: + + > sudo fscrypt lock --all-users %q`, e.DirPath) case *actions.ErrBadConfigFile: return `Either fix this file manually, or run "sudo fscrypt setup" to recreate it.` case *actions.ErrLoginProtectorName: @@ -183,30 +245,17 @@ func getErrorSuggestions(err error) string { -l". The limit can be modified by either changing the "memlock" item in /etc/security/limits.conf or by changing the "LimitMEMLOCK" value in systemd.` - case keyring.ErrKeyFilesOpen: - return `Directory was incompletely locked because some files are - still open. These files remain accessible. Try killing - any processes using files in the directory, then - re-running 'fscrypt lock'.` - case keyring.ErrKeyAddedByOtherUsers: - return `Directory couldn't be fully locked because other user(s) - have unlocked it. If you want to force the directory to - be locked, use 'sudo fscrypt lock --all-users DIR'.` case keyring.ErrV2PoliciesUnsupported: return fmt.Sprintf(`v2 encryption policies are only supported by kernel version 5.4 and later. Either use a newer kernel, or change policy_version to 1 in %s.`, actions.ConfigFileLocation) case ErrNoDestructiveOps: - return fmt.Sprintf("Use %s to automatically run destructive operations.", shortDisplay(forceFlag)) + return fmt.Sprintf("If desired, use %s to automatically run destructive operations.", + shortDisplay(forceFlag)) case ErrSpecifyProtector: return fmt.Sprintf("Use %s to specify a protector.", shortDisplay(protectorFlag)) case ErrSpecifyKeyFile: return fmt.Sprintf("Use %s to specify a key file.", shortDisplay(keyFileFlag)) - case ErrNotEmptyDir: - return `Encryption can only be setup on empty directories; files - cannot be encrypted in-place. Instead, encrypt an empty - directory, copy the files into that encrypted directory, - and securely delete the originals with "shred".` case ErrDropCachesPerm: return fmt.Sprintf(`Either this command should be run as root to properly clear the inode cache, or it should be run with -- cgit v1.2.3