]> git.apps.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)
committerPatrick Donnelly <pdonnell@redhat.com>
Wed, 16 Aug 2017 18:19:40 +0000 (11:19 -0700)
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>
src/client/Client.cc
src/mds/Server.cc

index c23f101177026f674ecc9148071bbae0182255c9..6ee1396ec7b328bca788b60b51cc3d877222c70e 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)