diff --git a/[refs] b/[refs] index 47750ec5028e..1a7ce14a2f94 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1ac564ecabc777636cf4eb88840802d7dc57d286 +refs/heads/master: 8a0ce7d99a4d19788e017f3138bc59b9962057ae diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 819545d21670..46934c97f8f7 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -364,14 +364,23 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, if (iap->ia_valid & ATTR_MODE) { iap->ia_mode &= S_IALLUGO; imode = iap->ia_mode |= (imode & ~S_IALLUGO); + /* if changing uid/gid revoke setuid/setgid in mode */ + if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) { + iap->ia_valid |= ATTR_KILL_PRIV; + iap->ia_mode &= ~S_ISUID; + } + if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) + iap->ia_mode &= ~S_ISGID; + } else { + /* + * Revoke setuid/setgid bit on chown/chgrp + */ + if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) + iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; + if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) + iap->ia_valid |= ATTR_KILL_SGID; } - /* Revoke setuid/setgid bit on chown/chgrp */ - if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) - iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; - if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) - iap->ia_valid |= ATTR_KILL_SGID; - /* Change the attributes. */ iap->ia_valid |= ATTR_CTIME;