]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs: clear suid/sgid if regular file is exe
authorPatrick Donnelly <pdonnell@redhat.com>
Wed, 16 Aug 2017 16:52:36 +0000 (09:52 -0700)
committerNathan Cutler <ncutler@suse.com>
Tue, 5 Sep 2017 09:28:00 +0000 (11:28 +0200)
According to [1], the suid/sgid should be cleared if any of the executable bits
are set.

Found this while experimenting for [2].

[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1480182

Fixes: http://tracker.ceph.com/issues/21004
Signed-off-by: Patrick Donnelly <pdonnell@redhat.com>
(cherry picked from commit d306d74a60e6d2c79aa4e9a840f3fc12ee8461bc)

src/client/Client.cc
src/mds/Server.cc

index fd1b0ae02b687b8065aaa7f98647d86054cbf0b5..e92675ec73fa2be3458921f1121d5db6d77d55b8 100644 (file)
@@ -6698,11 +6698,9 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask,
       mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
       mask &= ~CEPH_SETATTR_MODE;
       ldout(cct,10) << "changing mode to " << stx->stx_mode << dendl;
-    } else if (kill_sguid && S_ISREG(in->mode)) {
+    } else if (kill_sguid && S_ISREG(in->mode) && (in->mode & (S_IXUSR|S_IXGRP|S_IXOTH))) {
       /* Must squash the any setuid/setgid bits with an ownership change */
-      in->mode &= ~S_ISUID;
-      if ((in->mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP))
-       in->mode &= ~S_ISGID;
+      in->mode &= ~(S_ISUID|S_ISGID);
       mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
     }
 
index 952df343995eac50b17a691e53da796abedf97e2..19cc45ced7d5c2e1215ed5f507703a2f56e99ee6 100644 (file)
@@ -4068,10 +4068,9 @@ void Server::handle_client_setattr(MDRequestRef& mdr)
   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|CEPH_SETATTR_KILL_SGUID)) &&
-           S_ISREG(pi->mode)) {
-    pi->mode &= ~S_ISUID;
-    if ((pi->mode & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP))
-      pi->mode &= ~S_ISGID;
+           S_ISREG(pi->mode) &&
+            (pi->mode & (S_IXUSR|S_IXGRP|S_IXOTH))) {
+    pi->mode &= ~(S_ISUID|S_ISGID);
   }
 
   if (mask & CEPH_SETATTR_MTIME)