]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ceph: add some fscrypt guardrails wip-fscrypt-fnames
authorJeff Layton <jlayton@kernel.org>
Thu, 1 Jul 2021 18:40:51 +0000 (14:40 -0400)
committerJeff Layton <jlayton@kernel.org>
Tue, 7 Dec 2021 15:32:48 +0000 (10:32 -0500)
Ensure that we all into fscrypt to do a proper check for keys on link,
rename, etc.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c

index bf686e4af27a57a9467ddb782427f32f197b483f..37c9c589ee27b6107478a94b48550f833c903bfa 100644 (file)
@@ -1127,6 +1127,10 @@ static int ceph_link(struct dentry *old_dentry, struct inode *dir,
        if (ceph_snap(dir) != CEPH_NOSNAP)
                return -EROFS;
 
+       err = fscrypt_prepare_link(old_dentry, dir, dentry);
+       if (err)
+               return err;
+
        dout("link in dir %p old_dentry %p dentry %p\n", dir,
             old_dentry, dentry);
        req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LINK, USE_AUTH_MDS);
@@ -1324,6 +1328,10 @@ static int ceph_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
            (!ceph_quota_is_same_realm(old_dir, new_dir)))
                return -EXDEV;
 
+       err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
+       if (err)
+               return err;
+
        dout("rename dir %p dentry %p to dir %p dentry %p\n",
             old_dir, old_dentry, new_dir, new_dentry);
        req = ceph_mdsc_create_request(mdsc, op, USE_AUTH_MDS);
index c2e3e833ffc06e2573a9be461af6fb1c49747869..edc6c2c2517466d7be68c58c5f9e8eabe185d78c 100644 (file)
@@ -352,8 +352,13 @@ int ceph_open(struct inode *inode, struct file *file)
 
        /* filter out O_CREAT|O_EXCL; vfs did that already.  yuck. */
        flags = file->f_flags & ~(O_CREAT|O_EXCL);
-       if (S_ISDIR(inode->i_mode))
+       if (S_ISDIR(inode->i_mode)) {
                flags = O_DIRECTORY;  /* mds likes to know */
+       } else if (S_ISREG(inode->i_mode)) {
+               err = fscrypt_file_open(inode, file);
+               if (err)
+                       return err;
+       }
 
        dout("open inode %p ino %llx.%llx file %p flags %d (%d)\n", inode,
             ceph_vinop(inode), file, flags, file->f_flags);
@@ -704,6 +709,10 @@ retry:
                return -ENOENT;
        }
 
+       err = fscrypt_require_key(dir);
+       if (err)
+               return err;
+
        /* do the open */
        req = prepare_open_request(dir->i_sb, flags, mode);
        if (IS_ERR(req)) {
@@ -798,6 +807,13 @@ retry:
                dout("atomic_open finish_no_open on dn %p\n", dn);
                err = finish_no_open(file, dn);
        } else {
+               if (IS_ENCRYPTED(dir) &&
+                   !fscrypt_has_permitted_context(dir, d_inode(dentry))) {
+                       pr_warn("Inconsistent encryption context (parent %llx:%llx child %llx:%llx)\n",
+                               ceph_vinop(dir), ceph_vinop(d_inode(dentry)));
+                       goto out_req;
+               }
+
                dout("atomic_open finish_open on dn %p\n", dn);
                if (req->r_op == CEPH_MDS_OP_CREATE && req->r_reply_info.has_create_ino) {
                        struct inode *newino = d_inode(dentry);
index da242ff1756eea0f5a2a6569722a70a2f28b7bda..0dac3724c6122bdd189886086e25d8f09662741d 100644 (file)
@@ -2494,6 +2494,10 @@ int ceph_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
        if (ceph_inode_is_shutdown(inode))
                return -ESTALE;
 
+       err = fscrypt_prepare_setattr(dentry, attr);
+       if (err)
+               return err;
+
        err = setattr_prepare(&init_user_ns, dentry, attr);
        if (err != 0)
                return err;