diff options
author | Jeff Layton <jlayton@kernel.org> | 2023-05-17 12:26:44 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-06-21 14:54:14 +0200 |
commit | 8157832461bdae946485a17f7701c1215b85fd77 (patch) | |
tree | 65816e50336a8bee4be0e0b481ecd3a98ceb7bee | |
parent | 05f45f3981d392f9f3ced9bd5302ad981bb55499 (diff) | |
download | linux-stable-8157832461bdae946485a17f7701c1215b85fd77.tar.gz linux-stable-8157832461bdae946485a17f7701c1215b85fd77.tar.bz2 linux-stable-8157832461bdae946485a17f7701c1215b85fd77.zip |
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>
-rw-r--r-- | fs/nfsd/vfs.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index abc682854507..542a1adbbf2a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -545,7 +545,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)) |