mirror of
https://github.com/ceph/ceph
synced 2025-01-19 17:41:39 +00:00
Merge pull request #12331 from ceph/wip-jlayton-suid
Have ceph clear setuid/setgid bits on chown
This commit is contained in:
commit
07fd958b3c
@ -6494,15 +6494,8 @@ 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();
|
||||
@ -6510,6 +6503,7 @@ int Client::_do_setattr(Inode *in, struct ceph_statx *stx, int mask,
|
||||
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) {
|
||||
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -1694,11 +1694,48 @@ TEST(LibCephFS, SetSize) {
|
||||
|
||||
struct ceph_statx stx;
|
||||
uint64_t size = 8388608;
|
||||
stx.stx_size = (off_t)size;
|
||||
stx.stx_size = size;
|
||||
ASSERT_EQ(ceph_fsetattrx(cmount, fd, &stx, CEPH_SETATTR_SIZE), 0);
|
||||
ASSERT_EQ(ceph_fstatx(cmount, fd, &stx, CEPH_STATX_SIZE, 0), 0);
|
||||
ASSERT_EQ(stx.stx_size, (off_t)size);
|
||||
ASSERT_EQ(stx.stx_size, size);
|
||||
|
||||
ceph_close(cmount, fd);
|
||||
ceph_shutdown(cmount);
|
||||
}
|
||||
|
||||
TEST(LibCephFS, ClearSetuid) {
|
||||
struct ceph_mount_info *cmount;
|
||||
ASSERT_EQ(ceph_create(&cmount, NULL), 0);
|
||||
ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
|
||||
ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
|
||||
ASSERT_EQ(ceph_mount(cmount, "/"), 0);
|
||||
|
||||
Inode *root;
|
||||
ASSERT_EQ(ceph_ll_lookup_root(cmount, &root), 0);
|
||||
|
||||
char filename[32];
|
||||
sprintf(filename, "clearsetuid%x", getpid());
|
||||
|
||||
Fh *fh;
|
||||
Inode *in;
|
||||
struct ceph_statx stx;
|
||||
|
||||
ceph_ll_unlink(cmount, root, filename, ceph_mount_perms(cmount));
|
||||
ASSERT_EQ(ceph_ll_create(cmount, root, filename, 06555,
|
||||
O_RDWR|O_CREAT|O_EXCL, &in, &fh, &stx,
|
||||
CEPH_STATX_UID|CEPH_STATX_GID|CEPH_STATX_MODE, 0,
|
||||
ceph_mount_perms(cmount)), 0);
|
||||
|
||||
ASSERT_EQ(stx.stx_mode & 07777, 06555);
|
||||
|
||||
UserPerm *rootcred = ceph_userperm_new(0, 0, 0, NULL);
|
||||
ASSERT_TRUE(rootcred);
|
||||
stx.stx_uid++;
|
||||
stx.stx_gid++;
|
||||
ASSERT_EQ(ceph_ll_setattr(cmount, in, &stx, CEPH_SETATTR_UID|CEPH_SETATTR_GID, rootcred), 0);
|
||||
ASSERT_EQ(ceph_ll_getattr(cmount, in, &stx, CEPH_STATX_MODE, 0, ceph_mount_perms(cmount)), 0);
|
||||
ASSERT_TRUE(stx.stx_mask & CEPH_STATX_MODE);
|
||||
ASSERT_FALSE(stx.stx_mode & (S_ISUID|S_ISGID));
|
||||
|
||||
ceph_shutdown(cmount);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user