Commit d53d7008 authored by Jeff Layton's avatar Jeff Layton Committed by Chuck Lever
Browse files

nfsd: make a copy of struct iattr before calling notify_change



notify_change can modify the iattr structure. In particular it can
end up setting ATTR_MODE when ATTR_KILL_SUID is already set, causing
a BUG() if the same iattr is passed to notify_change more than once.

Make a copy of the struct iattr before calling notify_change.

Reported-by: default avatarZhi Li <yieli@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2207969


Tested-by: default avatarZhi Li <yieli@redhat.com>
Fixes: 34b91dda ("NFSD: Make nfsd4_setattr() wait before returning NFS4ERR_DELAY")
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 21a3f332
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -536,7 +536,15 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,

	inode_lock(inode);
	for (retries = 1;;) {
		host_err = __nfsd_setattr(dentry, iap);
		struct iattr attrs;

		/*
		 * notify_change() can alter its iattr argument, making
		 * @iap unsuitable for submission multiple times. Make a
		 * copy for every loop iteration.
		 */
		attrs = *iap;
		host_err = __nfsd_setattr(dentry, &attrs);
		if (host_err != -EAGAIN || !retries--)
			break;
		if (!nfsd_wait_for_delegreturn(rqstp, inode))