]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: clear setuid/setgid bits on ownership changes
authorJeff Layton <jlayton@redhat.com>
Mon, 5 Dec 2016 19:19:23 +0000 (14:19 -0500)
committerJeff Layton <jlayton@redhat.com>
Wed, 7 Dec 2016 17:10:56 +0000 (12:10 -0500)
If we get a ownership change, POSIX mandates that you clear the
setuid and setgid bits unless you are "appropriately privileged", in
which case the OS is allowed to leave them intact.

Linux however always clears those bits, regardless of the process
privileges, as that makes it simpler to close some potential races.
Have ceph do the same.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
src/mds/Server.cc

index 4f1057bf75491db74fd90eb1739bb1b7ac0c0048..1293d7d0bc2adc310493c55c044dd14c7990263e 100644 (file)
@@ -3793,13 +3793,20 @@ void Server::handle_client_setattr(MDRequestRef& mdr)
 
   pi = cur->project_inode();
 
-  if (mask & CEPH_SETATTR_MODE)
-    pi->mode = (pi->mode & ~07777) | (req->head.args.setattr.mode & 07777);
   if (mask & CEPH_SETATTR_UID)
     pi->uid = req->head.args.setattr.uid;
   if (mask & CEPH_SETATTR_GID)
     pi->gid = req->head.args.setattr.gid;
 
+  if (mask & CEPH_SETATTR_MODE)
+    pi->mode = (pi->mode & ~07777) | (req->head.args.setattr.mode & 07777);
+  else if ((mask & (CEPH_SETATTR_UID|CEPH_SETATTR_GID)) &&
+           S_ISREG(pi->mode)) {
+    pi->mode &= ~S_ISUID;
+    if ((pi->mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP))
+      pi->mode &= ~S_ISGID;
+  }
+
   if (mask & CEPH_SETATTR_MTIME)
     pi->mtime = req->head.args.setattr.mtime;
   if (mask & CEPH_SETATTR_ATIME)