add patch dont-read-blocks-from-disk-after-extents-being-swapped
[ext4-patch-queue.git] / crypto-move-context-consistency-check-to-ext4_file_open
blob369c68c7ba5be70cae01ab7a533b2bdf88bc4842
1 ext4 crypto: move context consistency check to ext4_file_open()
3 In the case where the per-file key for the directory is cached, but
4 root does not have access to the key needed to derive the per-file key
5 for the files in the directory, we allow the lookup to succeed, so
6 that lstat(2) and unlink(2) can suceed.  However, if a program tries
7 to open the file, it will get an ENOKEY error.
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 ---
11  fs/ext4/file.c  | 9 +++++++++
12  fs/ext4/namei.c | 8 ++++++--
13  2 files changed, 15 insertions(+), 2 deletions(-)
15 diff --git a/fs/ext4/file.c b/fs/ext4/file.c
16 index 1126436..474f1a4 100644
17 --- a/fs/ext4/file.c
18 +++ b/fs/ext4/file.c
19 @@ -350,6 +350,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
20         struct super_block *sb = inode->i_sb;
21         struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
22         struct vfsmount *mnt = filp->f_path.mnt;
23 +       struct inode *dir = filp->f_path.dentry->d_parent->d_inode;
24         struct path path;
25         char buf[64], *cp;
26         int ret;
27 @@ -393,6 +394,14 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
28                 if (ext4_encryption_info(inode) == NULL)
29                         return -ENOKEY;
30         }
31 +       if (ext4_encrypted_inode(dir) &&
32 +           !ext4_is_child_context_consistent_with_parent(dir, inode)) {
33 +               ext4_warning(inode->i_sb,
34 +                            "Inconsistent encryption contexts: %lu/%lu\n",
35 +                            (unsigned long) dir->i_ino,
36 +                            (unsigned long) inode->i_ino);
37 +               return -EPERM;
38 +       }
39         /*
40          * Set up the jbd2_inode if we are opening the inode for
41          * writing and the journal is present
42 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
43 index 5de8483..48e4b89 100644
44 --- a/fs/ext4/namei.c
45 +++ b/fs/ext4/namei.c
46 @@ -1603,11 +1603,15 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
47                         return ERR_PTR(-EFSCORRUPTED);
48                 }
49                 if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
50 -                   (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
51 -                    S_ISLNK(inode->i_mode)) &&
52 +                   (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
53                     !ext4_is_child_context_consistent_with_parent(dir,
54                                                                   inode)) {
55 +                       int nokey = ext4_encrypted_inode(inode) &&
56 +                               !ext4_encryption_info(inode);
58                         iput(inode);
59 +                       if (nokey)
60 +                               return ERR_PTR(-ENOKEY);
61                         ext4_warning(inode->i_sb,
62                                      "Inconsistent encryption contexts: %lu/%lu\n",
63                                      (unsigned long) dir->i_ino,