]> git.apps.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ceph: add some fscrypt guardrails
authorJeff Layton <jlayton@kernel.org>
Thu, 1 Jul 2021 18:40:51 +0000 (14:40 -0400)
committerXiubo Li <xiubli@redhat.com>
Thu, 18 Aug 2022 02:59:52 +0000 (10:59 +0800)
Add the appropriate calls into fscrypt for various actions, including
link, rename, setattr, and the open codepaths.

Reviewed-by: Xiubo Li <xiubli@redhat.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c

index 3f210cf8b057034b0ecc90286b5f4a6b3134abd3..b136fb923b7a08ba661564d4779c430ebf512ca7 100644 (file)
@@ -1138,6 +1138,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);
@@ -1379,6 +1383,10 @@ static int ceph_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
        if (err)
                return err;
 
+       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 04a2cc39da2d4b8bc43914bc39a779bf8d8cee8d..86265713a743589b4692e0302c89d4ba44879e28 100644 (file)
@@ -370,8 +370,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);
@@ -871,6 +876,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 2edda69daf28e03f37ff11331efa32c8b57a8658..79ff197c7cc5653f709c9827d698c88c408adc54 100644 (file)
@@ -2486,6 +2486,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;