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: Zhi Li <yieli@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2207969
Tested-by: Zhi Li <yieli@redhat.com>
Fixes: 34b91dda71
("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>
This commit is contained in:
parent
21a3f33289
commit
d53d70084d
|
@ -536,7 +536,15 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
|
||||||
|
|
||||||
inode_lock(inode);
|
inode_lock(inode);
|
||||||
for (retries = 1;;) {
|
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--)
|
if (host_err != -EAGAIN || !retries--)
|
||||||
break;
|
break;
|
||||||
if (!nfsd_wait_for_delegreturn(rqstp, inode))
|
if (!nfsd_wait_for_delegreturn(rqstp, inode))
|
||||||
|
|
Loading…
Reference in New Issue