Skip to content

Commit

Permalink
ext4 crypto: move context consistency check to ext4_file_open()
Browse files Browse the repository at this point in the history
In the case where the per-file key for the directory is cached, but
root does not have access to the key needed to derive the per-file key
for the files in the directory, we allow the lookup to succeed, so
that lstat(2) and unlink(2) can suceed.  However, if a program tries
to open the file, it will get an ENOKEY error.

Signed-off-by: Theodore Ts'o <[email protected]>
  • Loading branch information
tytso committed Feb 8, 2016
1 parent 28b4c26 commit ff978b0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
9 changes: 9 additions & 0 deletions fs/ext4/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
struct super_block *sb = inode->i_sb;
struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
struct vfsmount *mnt = filp->f_path.mnt;
struct inode *dir = filp->f_path.dentry->d_parent->d_inode;
struct path path;
char buf[64], *cp;
int ret;
Expand Down Expand Up @@ -393,6 +394,14 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
if (ext4_encryption_info(inode) == NULL)
return -ENOKEY;
}
if (ext4_encrypted_inode(dir) &&
!ext4_is_child_context_consistent_with_parent(dir, inode)) {
ext4_warning(inode->i_sb,
"Inconsistent encryption contexts: %lu/%lu\n",
(unsigned long) dir->i_ino,
(unsigned long) inode->i_ino);
return -EPERM;
}
/*
* Set up the jbd2_inode if we are opening the inode for
* writing and the journal is present
Expand Down
8 changes: 6 additions & 2 deletions fs/ext4/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -1603,11 +1603,15 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
return ERR_PTR(-EFSCORRUPTED);
}
if (!IS_ERR(inode) && ext4_encrypted_inode(dir) &&
(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)) &&
(S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
!ext4_is_child_context_consistent_with_parent(dir,
inode)) {
int nokey = ext4_encrypted_inode(inode) &&
!ext4_encryption_info(inode);

iput(inode);
if (nokey)
return ERR_PTR(-ENOKEY);
ext4_warning(inode->i_sb,
"Inconsistent encryption contexts: %lu/%lu\n",
(unsigned long) dir->i_ino,
Expand Down

0 comments on commit ff978b0

Please sign in to comment.