]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: clear setuid/setgid bits on ownership changes
authorJeff Layton <jlayton@redhat.com>
Tue, 20 Dec 2016 13:16:43 +0000 (08:16 -0500)
committerJeff Layton <jlayton@redhat.com>
Tue, 20 Dec 2016 13:16:43 +0000 (08:16 -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>
(cherry picked from commit 6da72500882d9749cb2be6eaa2568e6fe6e5ff4d)

src/mds/Server.cc

index 61320c3348d4febe6fd9d20fce47a71c0244154c..86be3f98f96eb99cbc6612e3f3b72760ebab6b11 100644 (file)
@@ -3788,13 +3788,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)