]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: allow setattr to change fscrypt_auth/file
authorJeff Layton <jlayton@redhat.com>
Wed, 5 May 2021 12:54:16 +0000 (08:54 -0400)
committerXiubo Li <xiubli@redhat.com>
Thu, 13 Jan 2022 13:08:42 +0000 (21:08 +0800)
Add new mask bits for those fields and update them if a setattr request
comes in with them.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
src/include/ceph_fs.h
src/include/cephfs/libcephfs.h
src/mds/Server.cc

index 2e3e119acccb2cf0ed48ba7ba067c019bedc5377..bf9bcbe011d18e5ca0e05ea81ec3577e9c6d6811 100644 (file)
@@ -426,19 +426,22 @@ enum {
 
 extern const char *ceph_mds_op_name(int op);
 
+// setattr mask is an int
 #ifndef CEPH_SETATTR_MODE
-#define CEPH_SETATTR_MODE      (1 << 0)
-#define CEPH_SETATTR_UID       (1 << 1)
-#define CEPH_SETATTR_GID       (1 << 2)
-#define CEPH_SETATTR_MTIME     (1 << 3)
-#define CEPH_SETATTR_ATIME     (1 << 4)
-#define CEPH_SETATTR_SIZE      (1 << 5)
-#define CEPH_SETATTR_CTIME     (1 << 6)
-#define CEPH_SETATTR_MTIME_NOW (1 << 7)
-#define CEPH_SETATTR_ATIME_NOW (1 << 8)
-#define CEPH_SETATTR_BTIME     (1 << 9)
+#define CEPH_SETATTR_MODE              (1 << 0)
+#define CEPH_SETATTR_UID               (1 << 1)
+#define CEPH_SETATTR_GID               (1 << 2)
+#define CEPH_SETATTR_MTIME             (1 << 3)
+#define CEPH_SETATTR_ATIME             (1 << 4)
+#define CEPH_SETATTR_SIZE              (1 << 5)
+#define CEPH_SETATTR_CTIME             (1 << 6)
+#define CEPH_SETATTR_MTIME_NOW         (1 << 7)
+#define CEPH_SETATTR_ATIME_NOW         (1 << 8)
+#define CEPH_SETATTR_BTIME             (1 << 9)
+#define CEPH_SETATTR_KILL_SGUID                (1 << 10)
+#define CEPH_SETATTR_FSCRYPT_AUTH      (1 << 11)
+#define CEPH_SETATTR_FSCRYPT_FILE      (1 << 12)
 #endif
-#define CEPH_SETATTR_KILL_SGUID        (1 << 10)
 
 /*
  * open request flags
index a348a5b6c00675c1de2379599b7b187c18406a89..443909996967ec6299a117b9e963929c85105843 100644 (file)
@@ -112,18 +112,21 @@ struct snap_info {
   struct snap_metadata *snap_metadata;
 };
 
-/* setattr mask bits */
+/* setattr mask bits (up to an int in size) */
 #ifndef CEPH_SETATTR_MODE
-# define CEPH_SETATTR_MODE     1
-# define CEPH_SETATTR_UID      2
-# define CEPH_SETATTR_GID      4
-# define CEPH_SETATTR_MTIME    8
-# define CEPH_SETATTR_ATIME    16
-# define CEPH_SETATTR_SIZE     32
-# define CEPH_SETATTR_CTIME    64
-# define CEPH_SETATTR_MTIME_NOW        128
-# define CEPH_SETATTR_ATIME_NOW        256
-# define CEPH_SETATTR_BTIME    512
+#define CEPH_SETATTR_MODE              (1 << 0)
+#define CEPH_SETATTR_UID               (1 << 1)
+#define CEPH_SETATTR_GID               (1 << 2)
+#define CEPH_SETATTR_MTIME             (1 << 3)
+#define CEPH_SETATTR_ATIME             (1 << 4)
+#define CEPH_SETATTR_SIZE              (1 << 5)
+#define CEPH_SETATTR_CTIME             (1 << 6)
+#define CEPH_SETATTR_MTIME_NOW         (1 << 7)
+#define CEPH_SETATTR_ATIME_NOW         (1 << 8)
+#define CEPH_SETATTR_BTIME             (1 << 9)
+#define CEPH_SETATTR_KILL_SGUID                (1 << 10)
+#define CEPH_SETATTR_FSCRYPT_AUTH      (1 << 11)
+#define CEPH_SETATTR_FSCRYPT_FILE      (1 << 12)
 #endif
 
 /* define error codes for the mount function*/
index 5212e2b28c93a4e3b0cc5850307a2eaa57a5e44a..2fb1de3a465f76de220351eab950a0952fe4a199 100644 (file)
@@ -5031,16 +5031,24 @@ void Server::handle_client_setattr(MDRequestRef& mdr)
   __u32 mask = req->head.args.setattr.mask;
   __u32 access_mask = MAY_WRITE;
 
-  // No changes to encrypted inodes from legacy clients
-  if (!cur->get_inode()->fscrypt_file.empty() && req->get_header().version < 6) {
-    respond_to_request(mdr, -CEPHFS_EPERM);
-    return;
+  if (req->get_header().version < 6) {
+    // No changes to fscrypted inodes by downrevved clients
+    if (!cur->get_inode()->fscrypt_auth.empty()) {
+      respond_to_request(mdr, -CEPHFS_EPERM);
+      return;
+    }
+
+    // Only allow fscrypt field changes by capable clients
+    if (mask & (CEPH_SETATTR_FSCRYPT_FILE|CEPH_SETATTR_FSCRYPT_AUTH)) {
+      respond_to_request(mdr, -CEPHFS_EINVAL);
+      return;
+    }
   }
 
   // xlock inode
-  if (mask & (CEPH_SETATTR_MODE|CEPH_SETATTR_UID|CEPH_SETATTR_GID|CEPH_SETATTR_BTIME|CEPH_SETATTR_KILL_SGUID))
+  if (mask & (CEPH_SETATTR_MODE|CEPH_SETATTR_UID|CEPH_SETATTR_GID|CEPH_SETATTR_BTIME|CEPH_SETATTR_KILL_SGUID|CEPH_SETATTR_FSCRYPT_AUTH))
     lov.add_xlock(&cur->authlock);
-  if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME|CEPH_SETATTR_SIZE))
+  if (mask & (CEPH_SETATTR_MTIME|CEPH_SETATTR_ATIME|CEPH_SETATTR_SIZE|CEPH_SETATTR_FSCRYPT_FILE))
     lov.add_xlock(&cur->filelock);
   if (mask & CEPH_SETATTR_CTIME)
     lov.add_wrlock(&cur->versionlock);
@@ -5120,10 +5128,6 @@ void Server::handle_client_setattr(MDRequestRef& mdr)
       pi.inode->size = req->head.args.setattr.size;
       pi.inode->rstat.rbytes = pi.inode->size;
     }
-    if (req->get_header().version >= 6) {
-      pi.inode->fscrypt_file = req->fscrypt_file;
-    }
-
     pi.inode->mtime = mdr->get_op_stamp();
 
     // adjust client's max_size?
@@ -5134,6 +5138,11 @@ void Server::handle_client_setattr(MDRequestRef& mdr)
     }
   }
 
+  if (mask & CEPH_SETATTR_FSCRYPT_AUTH)
+    pi.inode->fscrypt_auth = req->fscrypt_auth;
+  if (mask & CEPH_SETATTR_FSCRYPT_FILE)
+    pi.inode->fscrypt_file = req->fscrypt_file;
+
   pi.inode->version = cur->pre_dirty();
   pi.inode->ctime = mdr->get_op_stamp();
   if (mdr->get_op_stamp() > pi.inode->rstat.rctime)