ecryptfs_rename(): verify that lower dentries are still OK after lock_rename()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 10 Oct 2018 03:32:41 +0000 (23:32 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 10 Oct 2018 03:33:17 +0000 (23:33 -0400)
We get lower layer dentries, find their parents, do lock_rename() and
proceed to vfs_rename().  However, we do not check that dentries still
have the same parents and are not unlinked.  Need to check that...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/ecryptfs/inode.c

index 49121e5a8de228acfb1ea126250e5ad94e4ec812..5c36ceecb5c12828ceb84a39d19c86b69713b937 100644 (file)
@@ -593,11 +593,16 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        lower_new_dir_dentry = dget_parent(lower_new_dentry);
        target_inode = d_inode(new_dentry);
        trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
+       rc = -EINVAL;
+       if (lower_old_dentry->d_parent != lower_old_dir_dentry)
+               goto out_lock;
+       if (lower_new_dentry->d_parent != lower_new_dir_dentry)
+               goto out_lock;
+       if (d_unhashed(lower_old_dentry) || d_unhashed(lower_new_dentry))
+               goto out_lock;
        /* source should not be ancestor of target */
-       if (trap == lower_old_dentry) {
-               rc = -EINVAL;
+       if (trap == lower_old_dentry)
                goto out_lock;
-       }
        /* target should not be ancestor of source */
        if (trap == lower_new_dentry) {
                rc = -ENOTEMPTY;