Skip to content

Commit

Permalink
client: drop setuid/setgid bits on ownership change
Browse files Browse the repository at this point in the history
When we hold exclusive auth caps, then the client is responsible for
handling changes to the mode. Make sure we remove any setuid/setgid
bits on an ownership change.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
  • Loading branch information
jtlayton committed Dec 7, 2016
1 parent eab328b commit 36b4fd2
Showing 1 changed file with 21 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/client/Client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6494,22 +6494,16 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask,
}

if (in->caps_issued_mask(CEPH_CAP_AUTH_EXCL)) {
if (mask & CEPH_SETATTR_MODE) {
in->ctime = ceph_clock_now(cct);
in->cap_dirtier_uid = perms.uid();
in->cap_dirtier_gid = perms.gid();
in->mode = (in->mode & ~07777) | (stx->stx_mode & 07777);
mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
mask &= ~CEPH_SETATTR_MODE;
ldout(cct,10) << "changing mode to " << stx->stx_mode << dendl;
}
bool kill_sguid = false;

if (mask & CEPH_SETATTR_UID) {
in->ctime = ceph_clock_now(cct);
in->cap_dirtier_uid = perms.uid();
in->cap_dirtier_gid = perms.gid();
in->uid = stx->stx_uid;
mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
mask &= ~CEPH_SETATTR_UID;
kill_sguid = true;
ldout(cct,10) << "changing uid to " << stx->stx_uid << dendl;
}
if (mask & CEPH_SETATTR_GID) {
Expand All @@ -6519,8 +6513,26 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask,
in->gid = stx->stx_gid;
mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
mask &= ~CEPH_SETATTR_GID;
kill_sguid = true;
ldout(cct,10) << "changing gid to " << stx->stx_gid << dendl;
}

if (mask & CEPH_SETATTR_MODE) {
in->ctime = ceph_clock_now(cct);
in->cap_dirtier_uid = perms.uid();
in->cap_dirtier_gid = perms.gid();
in->mode = (in->mode & ~07777) | (stx->stx_mode & 07777);
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)) {
/* 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;
mark_caps_dirty(in, CEPH_CAP_AUTH_EXCL);
}

if (mask & CEPH_SETATTR_BTIME) {
in->ctime = ceph_clock_now(cct);
in->cap_dirtier_uid = perms.uid();
Expand Down

0 comments on commit 36b4fd2

Please sign in to comment.