fscrypt: use ENOKEY when file cannot be created w/o key
authorEric Biggers <ebiggers@google.com>
Mon, 5 Dec 2016 19:12:44 +0000 (11:12 -0800)
committerTheodore Ts'o <tytso@mit.edu>
Sat, 31 Dec 2016 21:26:20 +0000 (16:26 -0500)
As part of an effort to clean up fscrypt-related error codes, make
attempting to create a file in an encrypted directory that hasn't been
"unlocked" fail with ENOKEY.  Previously, several error codes were used
for this case, including ENOENT, EACCES, and EPERM, and they were not
consistent between and within filesystems.  ENOKEY is a better choice
because it expresses that the failure is due to lacking the encryption
key.  It also matches the error code returned when trying to open an
encrypted regular file without the key.

I am not aware of any users who might be relying on the previous
inconsistent error codes, which were never documented anywhere.

This failure case will be exercised by an xfstest.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/crypto/fname.c
fs/ext4/ialloc.c
fs/ext4/namei.c
fs/f2fs/dir.c
fs/f2fs/namei.c

index 56ad9d195f188892ecf74c41121e4861ecd6e57b..13052b85c3930f071be764c5fbbeb091429002d3 100644 (file)
@@ -332,7 +332,7 @@ int fscrypt_fname_usr_to_disk(struct inode *inode,
         * in a directory. Consequently, a user space name cannot be mapped to
         * a disk-space name
         */
-       return -EACCES;
+       return -ENOKEY;
 }
 EXPORT_SYMBOL(fscrypt_fname_usr_to_disk);
 
@@ -367,7 +367,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
                return 0;
        }
        if (!lookup)
-               return -EACCES;
+               return -ENOKEY;
 
        /*
         * We don't have the key and we are doing a lookup; decode the
index e57e8d90ea54a71745cf6257a7f1ef6437a0191b..f372fc431b8e036f11ba93388532cb1f0d6c5784 100644 (file)
@@ -771,7 +771,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
                if (err)
                        return ERR_PTR(err);
                if (!fscrypt_has_encryption_key(dir))
-                       return ERR_PTR(-EPERM);
+                       return ERR_PTR(-ENOKEY);
                if (!handle)
                        nblocks += EXT4_DATA_TRANS_BLOCKS(dir->i_sb);
                encrypt = 1;
index eadba919f26b1484c10125739a0e684fe49b7273..80b8afa4a8f9917343b22844341a2d07d361361c 100644 (file)
@@ -1378,6 +1378,8 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
                return NULL;
 
        retval = ext4_fname_setup_filename(dir, d_name, 1, &fname);
+       if (retval == -ENOENT)
+               return NULL;
        if (retval)
                return ERR_PTR(retval);
 
@@ -3088,7 +3090,7 @@ static int ext4_symlink(struct inode *dir,
                if (err)
                        return err;
                if (!fscrypt_has_encryption_key(dir))
-                       return -EPERM;
+                       return -ENOKEY;
                disk_link.len = (fscrypt_fname_encrypted_size(dir, len) +
                                 sizeof(struct fscrypt_symlink_data));
                sd = kzalloc(disk_link.len, GFP_KERNEL);
index 827c5daef4fca7d9168833ccc3388cd2dc6c071c..18607fc5240dafe4977f1e44532d4a33725a7623 100644 (file)
@@ -268,7 +268,10 @@ struct f2fs_dir_entry *f2fs_find_entry(struct inode *dir,
 
        err = fscrypt_setup_filename(dir, child, 1, &fname);
        if (err) {
-               *res_page = ERR_PTR(err);
+               if (err == -ENOENT)
+                       *res_page = NULL;
+               else
+                       *res_page = ERR_PTR(err);
                return NULL;
        }
 
index 56c19b0610a899a6351f72a16e26b788f956e3d5..11cabcadb1a33c5e868ca2115453a108184c215c 100644 (file)
@@ -403,7 +403,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
                        return err;
 
                if (!fscrypt_has_encryption_key(dir))
-                       return -EPERM;
+                       return -ENOKEY;
 
                disk_link.len = (fscrypt_fname_encrypted_size(dir, len) +
                                sizeof(struct fscrypt_symlink_data));
@@ -447,7 +447,7 @@ static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
                        goto err_out;
 
                if (!fscrypt_has_encryption_key(inode)) {
-                       err = -EPERM;
+                       err = -ENOKEY;
                        goto err_out;
                }