aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli-tests/t_lock.out15
-rwxr-xr-xcli-tests/t_lock.sh11
-rw-r--r--cmd/fscrypt/errors.go5
-rw-r--r--metadata/policy.go13
4 files changed, 44 insertions, 0 deletions
diff --git a/cli-tests/t_lock.out b/cli-tests/t_lock.out
index d630e74..ce27713 100644
--- a/cli-tests/t_lock.out
+++ b/cli-tests/t_lock.out
@@ -85,3 +85,18 @@ If you want to force the directory to be locked, use:
contents
"MNT/dir" is now locked.
cat: MNT/dir/file: No such file or directory
+
+# Try to operate on locked regular file
+"MNT/dir" is now locked.
+[ERROR] fscrypt status: cannot operate on locked regular file
+ "MNT/file"
+
+It is not possible to operate directly on a locked regular file, since the
+kernel does not support this. Specify the parent directory instead. (For loose
+files, any directory with the file's policy works.)
+[ERROR] fscrypt unlock: cannot operate on locked regular file
+ "MNT/file"
+
+It is not possible to operate directly on a locked regular file, since the
+kernel does not support this. Specify the parent directory instead. (For loose
+files, any directory with the file's policy works.)
diff --git a/cli-tests/t_lock.sh b/cli-tests/t_lock.sh
index 9b193fd..e5df4df 100755
--- a/cli-tests/t_lock.sh
+++ b/cli-tests/t_lock.sh
@@ -52,3 +52,14 @@ _expect_failure "fscrypt lock '$dir'"
cat "$dir/file"
fscrypt lock --all-users "$dir"
_expect_failure "cat '$dir/file'"
+
+_print_header "Try to operate on locked regular file"
+_reset_filesystems
+rm -rf "$dir"
+mkdir "$dir"
+echo hunter2 | fscrypt encrypt --quiet --name=prot "$dir"
+echo contents > "$dir/file"
+mv "$dir/file" "$MNT/file" # Make it a loose encrypted file.
+fscrypt lock "$dir"
+_expect_failure "fscrypt status '$MNT/file'"
+_expect_failure "fscrypt unlock '$MNT/file'"
diff --git a/cmd/fscrypt/errors.go b/cmd/fscrypt/errors.go
index 1ccf544..c4814f4 100644
--- a/cmd/fscrypt/errors.go
+++ b/cmd/fscrypt/errors.go
@@ -251,6 +251,11 @@ func getErrorSuggestions(err error) string {
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 *metadata.ErrLockedRegularFile:
+ return `It is not possible to operate directly on a locked
+ regular file, since the kernel does not support this.
+ Specify the parent directory instead. (For loose files,
+ any directory with the file's policy works.)`
}
switch errors.Cause(err) {
case crypto.ErrMlockUlimit:
diff --git a/metadata/policy.go b/metadata/policy.go
index 7831e53..fe6c38f 100644
--- a/metadata/policy.go
+++ b/metadata/policy.go
@@ -28,6 +28,7 @@ import (
"os"
"os/user"
"strconv"
+ "syscall"
"unsafe"
"github.com/pkg/errors"
@@ -85,6 +86,15 @@ func (err *ErrDirectoryNotOwned) Error() string {
write access to the directory.`, err.Path, owner)
}
+// ErrLockedRegularFile indicates that the path is a locked regular file.
+type ErrLockedRegularFile struct {
+ Path string
+}
+
+func (err *ErrLockedRegularFile) Error() string {
+ return fmt.Sprintf("cannot operate on locked regular file %q", err.Path)
+}
+
// ErrNotEncrypted indicates that the path is not encrypted.
type ErrNotEncrypted struct {
Path string
@@ -164,6 +174,9 @@ func buildV2PolicyData(policy *unix.FscryptPolicyV2) *PolicyData {
func GetPolicy(path string) (*PolicyData, error) {
file, err := os.Open(path)
if err != nil {
+ if err.(*os.PathError).Err == syscall.ENOKEY {
+ return nil, &ErrLockedRegularFile{path}
+ }
return nil, err
}
defer file.Close()