iattr::ia_size is a loff_t. decode_fattr4() dumps a full u64 value in there. If that value is larger than S64_MAX, then ia_size has underflowed. In this case the negative size is passed through to the VFS and underlying filesystems. I've observed XFS behavior: it returns EIO but still attempts to access past the end of the device. IOW it assumes the caller has already sanity-checked the value. Have our server return NFS4ERR_FBIG to the client when the passed-in file size cannot be held in a loff_t variable. > 15.1.4.4. NFS4ERR_FBIG (Error Code 27) > > The file is too large. The operation would have caused the file to > grow beyond the server's limit. It's likely that other NFSv4 operations that take a fattr4 argument (such as OPEN) have a similar issue). Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx> --- fs/nfsd/nfs4proc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index ed1ee25647be..b8ac2b9bce74 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -972,6 +972,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { + if (setattr->sa_iattr.ia_size < 0) + return nfserr_fbig; + status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh, &setattr->sa_stateid, WR_STATE, NULL, NULL);