aboutsummaryrefslogtreecommitdiff
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJeff Layton2023-05-17 12:26:44 -0400
committerGreg Kroah-Hartman2023-06-09 10:34:00 +0200
commitbd424277a1f86c41254d1068889908067d1f6aa5 (patch)
treeb15936c4e75386dd39ca0c9f81a166c0e4d02133 /fs/nfsd
parentdac09fec5b57377d4ac1f735762af939fff6fc06 (diff)
nfsd: make a copy of struct iattr before calling notify_change
[ Upstream commit d53d70084d27f56bcdf5074328f2c9ec861be596 ] 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: Zhi Li <yieli@redhat.com> Link: https://bugzilla.redhat.com/show_bug.cgi?id=2207969 Tested-by: Zhi Li <yieli@redhat.com> Fixes: 34b91dda7124 ("NFSD: Make nfsd4_setattr() wait before returning NFS4ERR_DELAY") Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/vfs.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index dc3ba13546dd..155b34c4683c 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -469,7 +469,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))