Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a0ce7d9 authored by Jeff Layton's avatar Jeff Layton Committed by Linus Torvalds
Browse files

knfsd: only set ATTR_KILL_S*ID if ATTR_MODE isn't being explicitly set



It's theoretically possible for a single SETATTR call to come in that sets the
mode and the uid/gid.  In that case, don't set the ATTR_KILL_S*ID bits since
that would trip the BUG() in notify_change.  Just fix up the mode to have the
same effect.

Signed-off-by: default avatarJeff Layton <jlayton@redhat.com>
Cc: Neil Brown <neilb@suse.de>
Cc: "J. Bruce Fields" <bfields@fieldses.org>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 1ac564ec
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -364,13 +364,22 @@ 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;
		}

	/* Revoke setuid/setgid bit on chown/chgrp */
		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;
	}

	/* Change the attributes. */